diff --git a/README.md b/README.md index ce5888c8..60c7306f 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,8 @@ Similarly to bearer token, the API Key Authentication also has the token entry k The API Key scheme has an additional property that requires where to add the API key in the request token: header, cookie or query. The inner provider takes care of that for you. +If an `Authorization` header is present, then the value of this header is used as API Key. This behaviour can be changed by setting the property `use-authorization-header-value` to `false`. + ### OAuth2 Authentication The extension will generate a `ClientRequestFilter` capable to add OAuth2 authentication capabilities to the OpenAPI operations that require it. This means that you can use diff --git a/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProvider.java b/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProvider.java index 93968948..56bed1ea 100644 --- a/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProvider.java +++ b/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProvider.java @@ -22,6 +22,7 @@ public class ApiKeyAuthenticationProvider extends AbstractAuthProvider { private static final Logger LOGGER = LoggerFactory.getLogger(ApiKeyAuthenticationProvider.class); static final String API_KEY = "api-key"; + static final String USE_AUTHORIZATION_HEADER_VALUE = "use-authorization-header-value"; private final ApiKeyIn apiKeyIn; private final String apiKeyName; @@ -43,11 +44,12 @@ public void filter(ClientRequestContext requestContext) throws IOException { requestContext.setUri(UriBuilder.fromUri(requestContext.getUri()).queryParam(apiKeyName, getApiKey()).build()); break; case cookie: - requestContext.getCookies().put(apiKeyName, new Cookie(apiKeyName, getApiKey())); + requestContext.getCookies().put(apiKeyName, new Cookie.Builder(apiKeyName).value(getApiKey()).build()); break; case header: if (requestContext.getHeaderString("Authorization") != null - && !requestContext.getHeaderString("Authorization").isEmpty()) { + && !requestContext.getHeaderString("Authorization").isEmpty() + && isUseAuthorizationHeaderValue()) { requestContext.getHeaders().putSingle(apiKeyName, requestContext.getHeaderString("Authorization")); } else requestContext.getHeaders().putSingle(apiKeyName, getApiKey()); @@ -63,6 +65,11 @@ private String getApiKey() { return key; } + private boolean isUseAuthorizationHeaderValue() { + final String value = getAuthConfigParam(USE_AUTHORIZATION_HEADER_VALUE, "true"); + return "true".equals(value); + } + private void validateConfig() { if (isTokenPropagation()) { throw new OpenApiGeneratorException( diff --git a/runtime/src/test/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProviderTest.java b/runtime/src/test/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProviderTest.java index 5a5584ac..f7417c62 100644 --- a/runtime/src/test/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProviderTest.java +++ b/runtime/src/test/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProviderTest.java @@ -23,6 +23,7 @@ class ApiKeyAuthenticationProviderTest extends AbstractAuthenticationProviderTes private static final String API_KEY_NAME = "API_KEY_NAME"; private static final String API_KEY_VALUE = "API_KEY_VALUE"; + private static final String API_KEY_AUTH_HEADER_VALUE = "API_KEY_AUTH_HEADER_VALUE"; private static final URI INVOKED_URI = URI.create("https://example.com/my-service"); @@ -42,6 +43,31 @@ protected ApiKeyAuthenticationProvider createProvider(String openApiSpecId, Stri openApiGeneratorConfig); } + @Test + void filterHeaderFromAuthorizationHeaderDefaultCase() throws IOException { + doReturn(API_KEY_AUTH_HEADER_VALUE).when(requestContext).getHeaderString("Authorization"); + provider.filter(requestContext); + assertHeader(headers, API_KEY_NAME, API_KEY_AUTH_HEADER_VALUE); + } + + @Test + void filterHeaderFromAuthorizationHeaderCase() throws IOException { + authConfig.authConfigParams.put(ApiKeyAuthenticationProvider.USE_AUTHORIZATION_HEADER_VALUE, "true"); + doReturn(API_KEY_AUTH_HEADER_VALUE).when(requestContext).getHeaderString("Authorization"); + provider.filter(requestContext); + assertHeader(headers, API_KEY_NAME, API_KEY_AUTH_HEADER_VALUE); + authConfig.authConfigParams.remove(ApiKeyAuthenticationProvider.USE_AUTHORIZATION_HEADER_VALUE); + } + + @Test + void filterHeaderNotFromAuthorizationHeaderCase() throws IOException { + authConfig.authConfigParams.put(ApiKeyAuthenticationProvider.USE_AUTHORIZATION_HEADER_VALUE, "false"); + doReturn(API_KEY_AUTH_HEADER_VALUE).when(requestContext).getHeaderString("Authorization"); + provider.filter(requestContext); + assertHeader(headers, API_KEY_NAME, API_KEY_VALUE); + authConfig.authConfigParams.remove(ApiKeyAuthenticationProvider.USE_AUTHORIZATION_HEADER_VALUE); + } + @Test void filterHeaderCase() throws IOException { provider.filter(requestContext);