in server/src/main/java/com/epam/aidial/core/server/Proxy.java [203:243]
private Future<AuthorizationResult> authorizeRequest(HttpServerRequest request) {
String apiKey = request.headers().get(HEADER_API_KEY);
String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
log.debug("Authorization header: {}", authorization);
if (apiKey == null && authorization == null) {
return Future.failedFuture(new HttpException(HttpStatus.UNAUTHORIZED, "At least API-KEY or Authorization header must be provided"));
}
if (apiKey != null && authorization == null) {
return apiKeyStore.getApiKeyData(apiKey)
.map(apiKeyData -> new AuthorizationResult(apiKeyData, null));
}
if (apiKey == null) {
return tokenValidator.extractClaims(authorization)
.compose(extractedClaims -> Future.succeededFuture(new AuthorizationResult(new ApiKeyData(), extractedClaims)),
error -> {
log.error("Can't extract claims from authorization header", error);
return Future.failedFuture(new HttpException(HttpStatus.UNAUTHORIZED, "Bad Authorization header"));
});
}
if (apiKey.equals(AccessTokenValidator.extractTokenFromHeader(authorization))) {
// we don't know exactly what kind of credentials a client provided to us.
// we try if it's access token the first and then API key
return tokenValidator.extractClaims(authorization)
.compose(claims -> Future.succeededFuture(new AuthorizationResult(new ApiKeyData(), claims)),
error -> apiKeyStore.getApiKeyData(apiKey).map(apiKeyData -> new AuthorizationResult(apiKeyData, null)));
}
// interceptor case
return apiKeyStore.getApiKeyData(apiKey)
.compose(apiKeyData -> {
if (apiKeyData.isInterceptor()) {
return Future.succeededFuture(new AuthorizationResult(apiKeyData, null));
} else {
return Future.failedFuture(new HttpException(HttpStatus.BAD_REQUEST, "Either API-KEY or Authorization header must be provided but not both"));
}
});
}