diff --git a/adapter/config/default_config.go b/adapter/config/default_config.go
index 75e57c01b7..c72370914b 100644
--- a/adapter/config/default_config.go
+++ b/adapter/config/default_config.go
@@ -228,7 +228,8 @@ var defaultConfig = &Config{
DropConsoleTestHeaders: true,
},
APIKeyConfig: apiKeyConfig{
- OAuthAgentURL: "https://localhost:9443",
+ InternalAPIKeyHeader: "Choreo-API-Key",
+ OAuthAgentURL: "https://localhost:9443",
},
PATConfig: patConfig{
TokenExpiryTimeSkew: 1,
diff --git a/adapter/config/types.go b/adapter/config/types.go
index 7ebabe44b1..f6969328d0 100644
--- a/adapter/config/types.go
+++ b/adapter/config/types.go
@@ -500,7 +500,8 @@ type authHeader struct {
}
type apiKeyConfig struct {
- OAuthAgentURL string `toml:"oauthAgentURL"`
+ InternalAPIKeyHeader string `toml:"internalAPIKeyHeader"`
+ OAuthAgentURL string `toml:"oauthAgentURL"`
}
type patConfig struct {
diff --git a/adapter/internal/discovery/xds/marshaller.go b/adapter/internal/discovery/xds/marshaller.go
index 73d676a81f..9cfaf65147 100644
--- a/adapter/internal/discovery/xds/marshaller.go
+++ b/adapter/internal/discovery/xds/marshaller.go
@@ -219,7 +219,8 @@ func MarshalConfig(config *config.Config) *enforcer.Config {
DropConsoleTestHeaders: config.Enforcer.Security.AuthHeader.DropConsoleTestHeaders,
},
ApiKeyConfig: &enforcer.APIKeyConfig{
- OauthAgentURL: config.Enforcer.Security.APIKeyConfig.OAuthAgentURL,
+ InternalAPIKeyHeader: config.Enforcer.Security.APIKeyConfig.InternalAPIKeyHeader,
+ OauthAgentURL: config.Enforcer.Security.APIKeyConfig.OAuthAgentURL,
},
PatConfig: &enforcer.PATConfig{
TokenExpiryTimeSkew: config.Enforcer.Security.PATConfig.TokenExpiryTimeSkew,
diff --git a/adapter/pkg/discovery/api/wso2/discovery/config/enforcer/api_key_config.pb.go b/adapter/pkg/discovery/api/wso2/discovery/config/enforcer/api_key_config.pb.go
index c701a7b285..926f99c7a5 100644
--- a/adapter/pkg/discovery/api/wso2/discovery/config/enforcer/api_key_config.pb.go
+++ b/adapter/pkg/discovery/api/wso2/discovery/config/enforcer/api_key_config.pb.go
@@ -25,7 +25,8 @@ type APIKeyConfig struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- OauthAgentURL string `protobuf:"bytes,1,opt,name=oauthAgentURL,proto3" json:"oauthAgentURL,omitempty"`
+ OauthAgentURL string `protobuf:"bytes,1,opt,name=oauthAgentURL,proto3" json:"oauthAgentURL,omitempty"`
+ InternalAPIKeyHeader string `protobuf:"bytes,2,opt,name=internalAPIKeyHeader,proto3" json:"internalAPIKeyHeader,omitempty"`
}
func (x *APIKeyConfig) Reset() {
@@ -67,6 +68,13 @@ func (x *APIKeyConfig) GetOauthAgentURL() string {
return ""
}
+func (x *APIKeyConfig) GetInternalAPIKeyHeader() string {
+ if x != nil {
+ return x.InternalAPIKeyHeader
+ }
+ return ""
+}
+
var File_wso2_discovery_config_enforcer_api_key_config_proto protoreflect.FileDescriptor
var file_wso2_discovery_config_enforcer_api_key_config_proto_rawDesc = []byte{
@@ -75,20 +83,24 @@ var file_wso2_discovery_config_enforcer_api_key_config_proto_rawDesc = []byte{
0x2f, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x77, 0x73, 0x6f, 0x32, 0x2e, 0x64, 0x69, 0x73, 0x63,
0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x66,
- 0x6f, 0x72, 0x63, 0x65, 0x72, 0x22, 0x34, 0x0a, 0x0c, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x43,
+ 0x6f, 0x72, 0x63, 0x65, 0x72, 0x22, 0x68, 0x0a, 0x0c, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x41, 0x67,
0x65, 0x6e, 0x74, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x61,
- 0x75, 0x74, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x55, 0x52, 0x4c, 0x42, 0x98, 0x01, 0x0a, 0x31,
- 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x73, 0x6f, 0x32, 0x2e, 0x63, 0x68, 0x6f, 0x72, 0x65, 0x6f, 0x2e,
- 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72,
- 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65,
- 0x72, 0x42, 0x11, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50,
- 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x67, 0x6f,
- 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x77,
- 0x73, 0x6f, 0x32, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x63, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x72, 0x3b, 0x65, 0x6e,
- 0x66, 0x6f, 0x72, 0x63, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x75, 0x74, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x55, 0x52, 0x4c, 0x12, 0x32, 0x0a, 0x14, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x61,
+ 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42,
+ 0x98, 0x01, 0x0a, 0x31, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x73, 0x6f, 0x32, 0x2e, 0x63, 0x68, 0x6f,
+ 0x72, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x63,
+ 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x66,
+ 0x6f, 0x72, 0x63, 0x65, 0x72, 0x42, 0x11, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4e, 0x67, 0x69, 0x74, 0x68,
+ 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x70, 0x72, 0x6f, 0x78,
+ 0x79, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x65, 0x2f, 0x77, 0x73, 0x6f, 0x32, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72,
+ 0x79, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65,
+ 0x72, 0x3b, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x33,
}
var (
diff --git a/api/proto/wso2/discovery/config/enforcer/api_key_config.proto b/api/proto/wso2/discovery/config/enforcer/api_key_config.proto
index 5c1eb80496..be64efdc12 100644
--- a/api/proto/wso2/discovery/config/enforcer/api_key_config.proto
+++ b/api/proto/wso2/discovery/config/enforcer/api_key_config.proto
@@ -9,4 +9,5 @@ option java_multiple_files = true;
message APIKeyConfig {
string oauthAgentURL = 1;
+ string internalAPIKeyHeader = 2;
}
diff --git a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfig.java b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfig.java
index d151a47f65..0305de475f 100644
--- a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfig.java
+++ b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfig.java
@@ -17,6 +17,7 @@ private APIKeyConfig(com.google.protobuf.GeneratedMessageV3.Builder> builder)
}
private APIKeyConfig() {
oauthAgentURL_ = "";
+ internalAPIKeyHeader_ = "";
}
@java.lang.Override
@@ -55,6 +56,12 @@ private APIKeyConfig(
oauthAgentURL_ = s;
break;
}
+ case 18: {
+ java.lang.String s = input.readStringRequireUtf8();
+
+ internalAPIKeyHeader_ = s;
+ break;
+ }
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
@@ -125,6 +132,44 @@ public java.lang.String getOauthAgentURL() {
}
}
+ public static final int INTERNALAPIKEYHEADER_FIELD_NUMBER = 2;
+ private volatile java.lang.Object internalAPIKeyHeader_;
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return The internalAPIKeyHeader.
+ */
+ @java.lang.Override
+ public java.lang.String getInternalAPIKeyHeader() {
+ java.lang.Object ref = internalAPIKeyHeader_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ internalAPIKeyHeader_ = s;
+ return s;
+ }
+ }
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return The bytes for internalAPIKeyHeader.
+ */
+ @java.lang.Override
+ public com.google.protobuf.ByteString
+ getInternalAPIKeyHeaderBytes() {
+ java.lang.Object ref = internalAPIKeyHeader_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ internalAPIKeyHeader_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
@@ -142,6 +187,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
if (!getOauthAgentURLBytes().isEmpty()) {
com.google.protobuf.GeneratedMessageV3.writeString(output, 1, oauthAgentURL_);
}
+ if (!getInternalAPIKeyHeaderBytes().isEmpty()) {
+ com.google.protobuf.GeneratedMessageV3.writeString(output, 2, internalAPIKeyHeader_);
+ }
unknownFields.writeTo(output);
}
@@ -154,6 +202,9 @@ public int getSerializedSize() {
if (!getOauthAgentURLBytes().isEmpty()) {
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, oauthAgentURL_);
}
+ if (!getInternalAPIKeyHeaderBytes().isEmpty()) {
+ size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, internalAPIKeyHeader_);
+ }
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
@@ -171,6 +222,8 @@ public boolean equals(final java.lang.Object obj) {
if (!getOauthAgentURL()
.equals(other.getOauthAgentURL())) return false;
+ if (!getInternalAPIKeyHeader()
+ .equals(other.getInternalAPIKeyHeader())) return false;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@@ -184,6 +237,8 @@ public int hashCode() {
hash = (19 * hash) + getDescriptor().hashCode();
hash = (37 * hash) + OAUTHAGENTURL_FIELD_NUMBER;
hash = (53 * hash) + getOauthAgentURL().hashCode();
+ hash = (37 * hash) + INTERNALAPIKEYHEADER_FIELD_NUMBER;
+ hash = (53 * hash) + getInternalAPIKeyHeader().hashCode();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
@@ -319,6 +374,8 @@ public Builder clear() {
super.clear();
oauthAgentURL_ = "";
+ internalAPIKeyHeader_ = "";
+
return this;
}
@@ -346,6 +403,7 @@ public org.wso2.choreo.connect.discovery.config.enforcer.APIKeyConfig build() {
public org.wso2.choreo.connect.discovery.config.enforcer.APIKeyConfig buildPartial() {
org.wso2.choreo.connect.discovery.config.enforcer.APIKeyConfig result = new org.wso2.choreo.connect.discovery.config.enforcer.APIKeyConfig(this);
result.oauthAgentURL_ = oauthAgentURL_;
+ result.internalAPIKeyHeader_ = internalAPIKeyHeader_;
onBuilt();
return result;
}
@@ -398,6 +456,10 @@ public Builder mergeFrom(org.wso2.choreo.connect.discovery.config.enforcer.APIKe
oauthAgentURL_ = other.oauthAgentURL_;
onChanged();
}
+ if (!other.getInternalAPIKeyHeader().isEmpty()) {
+ internalAPIKeyHeader_ = other.internalAPIKeyHeader_;
+ onChanged();
+ }
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
@@ -502,6 +564,82 @@ public Builder setOauthAgentURLBytes(
onChanged();
return this;
}
+
+ private java.lang.Object internalAPIKeyHeader_ = "";
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return The internalAPIKeyHeader.
+ */
+ public java.lang.String getInternalAPIKeyHeader() {
+ java.lang.Object ref = internalAPIKeyHeader_;
+ if (!(ref instanceof java.lang.String)) {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ internalAPIKeyHeader_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return The bytes for internalAPIKeyHeader.
+ */
+ public com.google.protobuf.ByteString
+ getInternalAPIKeyHeaderBytes() {
+ java.lang.Object ref = internalAPIKeyHeader_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ internalAPIKeyHeader_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @param value The internalAPIKeyHeader to set.
+ * @return This builder for chaining.
+ */
+ public Builder setInternalAPIKeyHeader(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ internalAPIKeyHeader_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return This builder for chaining.
+ */
+ public Builder clearInternalAPIKeyHeader() {
+
+ internalAPIKeyHeader_ = getDefaultInstance().getInternalAPIKeyHeader();
+ onChanged();
+ return this;
+ }
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @param value The bytes for internalAPIKeyHeader to set.
+ * @return This builder for chaining.
+ */
+ public Builder setInternalAPIKeyHeaderBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ checkByteStringIsUtf8(value);
+
+ internalAPIKeyHeader_ = value;
+ onChanged();
+ return this;
+ }
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
diff --git a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigOrBuilder.java b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigOrBuilder.java
index 6a44e7b39c..18f20034b8 100644
--- a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigOrBuilder.java
+++ b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigOrBuilder.java
@@ -18,4 +18,16 @@ public interface APIKeyConfigOrBuilder extends
*/
com.google.protobuf.ByteString
getOauthAgentURLBytes();
+
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return The internalAPIKeyHeader.
+ */
+ java.lang.String getInternalAPIKeyHeader();
+ /**
+ * string internalAPIKeyHeader = 2;
+ * @return The bytes for internalAPIKeyHeader.
+ */
+ com.google.protobuf.ByteString
+ getInternalAPIKeyHeaderBytes();
}
diff --git a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigProto.java b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigProto.java
index fce84732e5..d9638eaa47 100644
--- a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigProto.java
+++ b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/config/enforcer/APIKeyConfigProto.java
@@ -30,12 +30,12 @@ public static void registerAllExtensions(
java.lang.String[] descriptorData = {
"\n3wso2/discovery/config/enforcer/api_key" +
"_config.proto\022\036wso2.discovery.config.enf" +
- "orcer\"%\n\014APIKeyConfig\022\025\n\roauthAgentURL\030\001" +
- " \001(\tB\230\001\n1org.wso2.choreo.connect.discove" +
- "ry.config.enforcerB\021APIKeyConfigProtoP\001Z" +
- "Ngithub.com/envoyproxy/go-control-plane/" +
- "wso2/discovery/config/enforcer;enforcerb" +
- "\006proto3"
+ "orcer\"C\n\014APIKeyConfig\022\025\n\roauthAgentURL\030\001" +
+ " \001(\t\022\034\n\024internalAPIKeyHeader\030\002 \001(\tB\230\001\n1o" +
+ "rg.wso2.choreo.connect.discovery.config." +
+ "enforcerB\021APIKeyConfigProtoP\001ZNgithub.co" +
+ "m/envoyproxy/go-control-plane/wso2/disco" +
+ "very/config/enforcer;enforcerb\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
@@ -46,7 +46,7 @@ public static void registerAllExtensions(
internal_static_wso2_discovery_config_enforcer_APIKeyConfig_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_wso2_discovery_config_enforcer_APIKeyConfig_descriptor,
- new java.lang.String[] { "OauthAgentURL", });
+ new java.lang.String[] { "OauthAgentURL", "InternalAPIKeyHeader", });
}
// @@protoc_insertion_point(outer_class_scope)
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/ConfigHolder.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/ConfigHolder.java
index 1f23e3da71..148bf9a3f6 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/ConfigHolder.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/ConfigHolder.java
@@ -224,6 +224,7 @@ private void populateAuthHeaderConfigurations(AuthHeader authHeader) {
private void populateAPIKeyConfigs(APIKeyConfig apiKeyConfig) {
APIKeyDTO apiKeyDTO = new APIKeyDTO();
+ apiKeyDTO.setApiKeyInternalHeader(apiKeyConfig.getInternalAPIKeyHeader());
apiKeyDTO.setOauthAgentURL(apiKeyConfig.getOauthAgentURL());
config.setApiKeyConfig(apiKeyDTO);
}
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/dto/APIKeyDTO.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/dto/APIKeyDTO.java
index 759e544628..1dab51cb5f 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/dto/APIKeyDTO.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/config/dto/APIKeyDTO.java
@@ -23,8 +23,17 @@
*/
public class APIKeyDTO {
+ private String apiKeyInternalHeader;
private String oauthAgentURL;
+ public String getApiKeyInternalHeader() {
+ return apiKeyInternalHeader;
+ }
+
+ public void setApiKeyInternalHeader(String apiKeyInternalHeader) {
+ this.apiKeyInternalHeader = apiKeyInternalHeader;
+ }
+
public String getOauthAgentURL() {
return oauthAgentURL;
}
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
index 0418fc7a47..b604613e21 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
@@ -33,7 +33,7 @@
import org.wso2.choreo.connect.enforcer.constants.AdapterConstants;
import org.wso2.choreo.connect.enforcer.constants.InterceptorConstants;
import org.wso2.choreo.connect.enforcer.exception.APISecurityException;
-import org.wso2.choreo.connect.enforcer.security.jwt.APIKeyAuthenticator;
+import org.wso2.choreo.connect.enforcer.security.jwt.ChoreoAPIKeyAuthenticator;
import org.wso2.choreo.connect.enforcer.security.jwt.InternalAPIKeyAuthenticator;
import org.wso2.choreo.connect.enforcer.security.jwt.JWTAuthenticator;
import org.wso2.choreo.connect.enforcer.security.jwt.UnsecuredAPIAuthenticator;
@@ -98,8 +98,8 @@ private void initializeAuthenticators(APIConfig apiConfig) {
}
if (isApiKeyProtected) {
- APIKeyAuthenticator apiKeyAuthenticator = new APIKeyAuthenticator();
- authenticators.add(apiKeyAuthenticator);
+ ChoreoAPIKeyAuthenticator choreoApiKeyAuthenticator = new ChoreoAPIKeyAuthenticator();
+ authenticators.add(choreoApiKeyAuthenticator);
}
Authenticator authenticator = new InternalAPIKeyAuthenticator(
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyConstants.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyConstants.java
index 5345377ed1..82fc8613ba 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyConstants.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyConstants.java
@@ -24,8 +24,10 @@
public class APIKeyConstants {
public static final String PAT_PREFIX = "chp_";
+ public static final String API_KEY_PREFIX = "chk_";
public static final String API_KEY_JSON_KEY = "key";
- public static final String PAT_EXCHANGE_ENDPOINT = "/auth/pat";
+ public static final String PAT_EXCHANGE_ENDPOINT = "/internal/pat";
+ public static final String API_KEY_EXCHANGE_ENDPOINT = "/internal/apiKey/token";
}
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyUtils.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyUtils.java
index 55e1c021ca..a861fe162a 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyUtils.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyUtils.java
@@ -95,12 +95,12 @@ public static String generateAPIKeyHash(String apiKey) {
}
/**
- * This function exchanges a given API key to an JWT token.
+ * This function exchanges a given PAT hash to an JWT token.
*
- * @param keyHash Key Hash
+ * @param patHash Key Hash
* @return JWT corresponding to given PAT.
*/
- public static Optional exchangePATToJWT(String keyHash) {
+ public static Optional exchangePATToJWT(String patHash) {
URL url = null;
try {
@@ -115,7 +115,45 @@ public static Optional exchangePATToJWT(String keyHash) {
// Create a request to exchange API key to JWT.
HttpPost exchangeRequest = new HttpPost(url.toURI());
exchangeRequest.addHeader("Content-Type", ContentType.APPLICATION_JSON.toString());
- exchangeRequest.setEntity(new StringEntity(createPATExchangeRequest(keyHash)));
+ exchangeRequest.setEntity(new StringEntity(createKeyHashExchangeRequest(patHash)));
+ try (CloseableHttpResponse response = httpClient.execute(exchangeRequest)) {
+ if (response.getStatusLine().getStatusCode() == 200) {
+ HttpEntity entity = response.getEntity();
+ try (InputStream content = entity.getContent()) {
+ OAuthAgentResponse resp = gson.fromJson(IOUtils.toString(content),
+ OAuthAgentResponse.class);
+ return Optional.of(resp.getAccessToken());
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("Error occurred while exchanging API key to JWT", e);
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Exchange a given API key hash to a JWT token.
+ *
+ * @param apiKeyHash API Key Hash
+ * @return JWT corresponding to given API Key.
+ */
+ public static Optional exchangeAPIKeyToJWT(String apiKeyHash) {
+
+ URL url = null;
+ try {
+ String apiKeyExchangeURL = String.format("%s%s", ConfigHolder.getInstance().getConfig()
+ .getApiKeyConfig().getOauthAgentURL(), APIKeyConstants.API_KEY_EXCHANGE_ENDPOINT);
+ url = new URL(apiKeyExchangeURL);
+ } catch (MalformedURLException e) {
+ log.error("Error occurred while parsing OAuth agent URL", e);
+ return Optional.empty();
+ }
+ try (CloseableHttpClient httpClient = (CloseableHttpClient) FilterUtils.getHttpClient(url.getProtocol())) {
+ // Create a request to exchange API key to JWT.
+ HttpPost exchangeRequest = new HttpPost(url.toURI());
+ exchangeRequest.addHeader("Content-Type", ContentType.APPLICATION_JSON.toString());
+ exchangeRequest.setEntity(new StringEntity(createKeyHashExchangeRequest(apiKeyHash)));
try (CloseableHttpResponse response = httpClient.execute(exchangeRequest)) {
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
@@ -161,7 +199,7 @@ private static String generateCRC32Checksum(String data) {
return Base64.getEncoder().withoutPadding().encodeToString(checksumBytes);
}
- private static String createPATExchangeRequest(String keyHash) {
+ private static String createKeyHashExchangeRequest(String keyHash) {
Map patRequest = new HashMap<>();
patRequest.put("apiKeyHash", keyHash);
return gson.toJson(patRequest);
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/ChoreoAPIKeyAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/ChoreoAPIKeyAuthenticator.java
new file mode 100644
index 0000000000..22a2737799
--- /dev/null
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/ChoreoAPIKeyAuthenticator.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.choreo.connect.enforcer.security.jwt;
+
+import net.minidev.json.JSONObject;
+import net.minidev.json.JSONValue;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.wso2.choreo.connect.enforcer.commons.model.AuthenticationContext;
+import org.wso2.choreo.connect.enforcer.commons.model.RequestContext;
+import org.wso2.choreo.connect.enforcer.config.ConfigHolder;
+import org.wso2.choreo.connect.enforcer.constants.APIConstants;
+import org.wso2.choreo.connect.enforcer.exception.APISecurityException;
+import org.wso2.choreo.connect.enforcer.security.jwt.validator.JWTConstants;
+
+import java.util.Base64;
+import java.util.Map;
+
+/**
+ * API Key authenticator.
+ */
+public class ChoreoAPIKeyAuthenticator extends JWTAuthenticator {
+
+ private static final Logger log = LogManager.getLogger(ChoreoAPIKeyAuthenticator.class);
+
+ private static boolean isAPIKeyEnabled = false;
+
+ static {
+ if (System.getenv("API_KEY_ENABLED") != null) {
+ isAPIKeyEnabled = Boolean.parseBoolean(System.getenv("API_KEY_ENABLED"));
+ }
+ }
+
+ public ChoreoAPIKeyAuthenticator() {
+ super();
+ log.debug("API key authenticator initialized.");
+ }
+
+ @Override
+ public boolean canAuthenticate(RequestContext requestContext) {
+
+ if (!isAPIKeyEnabled) {
+ return false;
+ }
+ String apiKeyValue = getAPIKeyFromRequest(requestContext);
+ return apiKeyValue != null && apiKeyValue.startsWith(APIKeyConstants.API_KEY_PREFIX);
+ }
+
+ @Override
+ public AuthenticationContext authenticate(RequestContext requestContext) throws APISecurityException {
+
+ String apiKeyHeaderValue = getAPIKeyFromRequest(requestContext);
+ // Skipping the prefix(`chk_`) and checksum.
+ String apiKeyData = apiKeyHeaderValue.substring(4, apiKeyHeaderValue.length() - 6);
+ // Base 64 decode key data.
+ String decodedKeyData = new String(Base64.getDecoder().decode(apiKeyData));
+ // Convert data into JSON.
+ JSONObject jsonObject = (JSONObject) JSONValue.parse(decodedKeyData);
+ // Extracting the jwt token.
+ String jwtToken = jsonObject.getAsString(APIKeyConstants.API_KEY_JSON_KEY);
+ // Add the JWT as the Authorization header to authenticate the request.
+ requestContext.getHeaders().put(APIConstants.AUTHORIZATION_HEADER_DEFAULT,
+ JWTConstants.BEARER + " " + jwtToken);
+ return super.authenticate(requestContext);
+ }
+
+ private String getAPIKeyFromRequest(RequestContext requestContext) {
+ Map headers = requestContext.getHeaders();
+ return headers.get(ConfigHolder.getInstance().getConfig().getApiKeyConfig().getApiKeyInternalHeader());
+ }
+
+ @Override
+ public String getChallengeString() {
+ return "";
+ }
+
+ @Override
+ public String getName() {
+ return "Choreo API Key";
+ }
+
+ @Override
+ public int getPriority() {
+ return 15;
+ }
+}