use of io.swagger.v3.oas.annotations.headers.Header in project carbon-apimgt by wso2.
the class OASParserUtil method processReferenceObjectMap.
private static void processReferenceObjectMap(SwaggerUpdateContext context) {
// Get a deep copy of the reference objects in order to prevent Concurrent modification exception
// since we may need to update the reference object mapping while iterating through it
Map<String, Set<String>> referenceObjectsMappingCopy = getReferenceObjectsCopy(context.getReferenceObjectMapping());
int preRefObjectCount = getReferenceObjectCount(context.getReferenceObjectMapping());
Set<Components> aggregatedComponents = context.getAggregatedComponents();
for (Components sourceComponents : aggregatedComponents) {
for (Map.Entry<String, Set<String>> refCategoryEntry : referenceObjectsMappingCopy.entrySet()) {
String category = refCategoryEntry.getKey();
if (REQUEST_BODIES.equalsIgnoreCase(category)) {
Map<String, RequestBody> sourceRequestBodies = sourceComponents.getRequestBodies();
if (sourceRequestBodies != null) {
for (String refKey : refCategoryEntry.getValue()) {
RequestBody requestBody = sourceRequestBodies.get(refKey);
setRefOfRequestBody(requestBody, context);
}
}
}
if (SCHEMAS.equalsIgnoreCase(category)) {
Map<String, Schema> sourceSchemas = sourceComponents.getSchemas();
if (sourceSchemas != null) {
for (String refKey : refCategoryEntry.getValue()) {
Schema schema = sourceSchemas.get(refKey);
extractReferenceFromSchema(schema, context);
}
}
}
if (PARAMETERS.equalsIgnoreCase(category)) {
Map<String, Parameter> parameters = sourceComponents.getParameters();
if (parameters != null) {
for (String refKey : refCategoryEntry.getValue()) {
Parameter parameter = parameters.get(refKey);
// Extract the parameter reference only if it exists in the source definition
if (parameter != null) {
Content content = parameter.getContent();
if (content != null) {
extractReferenceFromContent(content, context);
} else {
String ref = parameter.get$ref();
if (ref != null) {
extractReferenceWithoutSchema(ref, context);
}
}
}
}
}
}
if (RESPONSES.equalsIgnoreCase(category)) {
Map<String, ApiResponse> responses = sourceComponents.getResponses();
if (responses != null) {
for (String refKey : refCategoryEntry.getValue()) {
ApiResponse response = responses.get(refKey);
// Extract the response reference only if it exists in the source definition
if (response != null) {
Content content = response.getContent();
extractReferenceFromContent(content, context);
}
}
}
}
if (HEADERS.equalsIgnoreCase(category)) {
Map<String, Header> headers = sourceComponents.getHeaders();
if (headers != null) {
for (String refKey : refCategoryEntry.getValue()) {
Header header = headers.get(refKey);
Content content = header.getContent();
extractReferenceFromContent(content, context);
}
}
}
}
int postRefObjectCount = getReferenceObjectCount(context.getReferenceObjectMapping());
if (postRefObjectCount > preRefObjectCount) {
processReferenceObjectMap(context);
}
}
}
use of io.swagger.v3.oas.annotations.headers.Header in project carbon-apimgt by wso2.
the class ApiKeyAuthenticator method authenticate.
@Override
public AuthenticationResponse authenticate(MessageContext synCtx) {
if (log.isDebugEnabled()) {
log.info("ApiKey Authentication initialized");
}
try {
// Extract apikey from the request while removing it from the msg context.
String apiKey = extractApiKey(synCtx);
JWTTokenPayloadInfo payloadInfo = null;
if (jwtConfigurationDto == null) {
jwtConfigurationDto = ServiceReferenceHolder.getInstance().getAPIManagerConfiguration().getJwtConfigurationDto();
}
if (jwtGenerationEnabled == null) {
jwtGenerationEnabled = jwtConfigurationDto.isEnabled();
}
if (apiMgtGatewayJWTGenerator == null) {
apiMgtGatewayJWTGenerator = ServiceReferenceHolder.getInstance().getApiMgtGatewayJWTGenerator().get(jwtConfigurationDto.getGatewayJWTGeneratorImpl());
}
String[] splitToken = apiKey.split("\\.");
JWSHeader decodedHeader;
JWTClaimsSet payload = null;
SignedJWT signedJWT = null;
String tokenIdentifier, certAlias;
if (splitToken.length != 3) {
log.error("Api Key does not have the format {header}.{payload}.{signature} ");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
signedJWT = SignedJWT.parse(apiKey);
payload = signedJWT.getJWTClaimsSet();
decodedHeader = signedJWT.getHeader();
tokenIdentifier = payload.getJWTID();
// Check if the decoded header contains type as 'JWT'.
if (!JOSEObjectType.JWT.equals(decodedHeader.getType())) {
if (log.isDebugEnabled()) {
log.debug("Invalid Api Key token type. Api Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Api Key token type.");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
if (!GatewayUtils.isAPIKey(payload)) {
log.error("Invalid Api Key. Internal Key Sent");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
if (decodedHeader.getKeyID() == null) {
if (log.isDebugEnabled()) {
log.debug("Invalid Api Key. Could not find alias in header. Api Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Api Key. Could not find alias in header");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
} else {
certAlias = decodedHeader.getKeyID();
}
String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
String httpMethod = (String) ((Axis2MessageContext) synCtx).getAxis2MessageContext().getProperty(Constants.Configuration.HTTP_METHOD);
String matchingResource = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
OpenAPI openAPI = (OpenAPI) synCtx.getProperty(APIMgtGatewayConstants.OPEN_API_OBJECT);
if (openAPI == null && !APIConstants.GRAPHQL_API.equals(synCtx.getProperty(APIConstants.API_TYPE))) {
log.error("Swagger is missing in the gateway. " + "Therefore, Api Key authentication cannot be performed.");
return new AuthenticationResponse(false, isMandatory, true, APISecurityConstants.API_AUTH_MISSING_OPEN_API_DEF, APISecurityConstants.API_AUTH_MISSING_OPEN_API_DEF_ERROR_MESSAGE);
}
String resourceCacheKey = APIUtil.getResourceInfoDTOCacheKey(apiContext, apiVersion, matchingResource, httpMethod);
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setHttpVerb(httpMethod);
// Not doing resource level authentication
verbInfoDTO.setAuthType(APIConstants.AUTH_NO_AUTHENTICATION);
verbInfoDTO.setRequestKey(resourceCacheKey);
verbInfoDTO.setThrottling(OpenAPIUtils.getResourceThrottlingTier(openAPI, synCtx));
List<VerbInfoDTO> verbInfoList = new ArrayList<>();
verbInfoList.add(verbInfoDTO);
synCtx.setProperty(APIConstants.VERB_INFO_DTO, verbInfoList);
String cacheKey = GatewayUtils.getAccessTokenCacheKey(tokenIdentifier, apiContext, apiVersion, matchingResource, httpMethod);
String tenantDomain = GatewayUtils.getTenantDomain();
boolean isVerified = false;
// Validate from cache
if (isGatewayTokenCacheEnabled == null) {
isGatewayTokenCacheEnabled = GatewayUtils.isGatewayTokenCacheEnabled();
}
if (isGatewayTokenCacheEnabled) {
String cacheToken = (String) getGatewayApiKeyCache().get(tokenIdentifier);
if (cacheToken != null) {
if (log.isDebugEnabled()) {
log.debug("Api Key retrieved from the Api Key cache.");
}
if (getGatewayApiKeyDataCache().get(cacheKey) != null) {
// Token is found in the key cache
payloadInfo = (JWTTokenPayloadInfo) getGatewayApiKeyDataCache().get(cacheKey);
String accessToken = payloadInfo.getAccessToken();
if (!accessToken.equals(apiKey)) {
isVerified = false;
} else {
isVerified = true;
}
}
} else if (getInvalidGatewayApiKeyCache().get(tokenIdentifier) != null) {
if (log.isDebugEnabled()) {
log.debug("Api Key retrieved from the invalid Api Key cache. Api Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Api Key." + GatewayUtils.getMaskedToken(splitToken[0]));
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
} else if (RevokedJWTDataHolder.isJWTTokenSignatureExistsInRevokedMap(tokenIdentifier)) {
if (log.isDebugEnabled()) {
log.debug("Token retrieved from the revoked jwt token map. Token: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid API Key. " + GatewayUtils.getMaskedToken(splitToken[0]));
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid API Key");
}
} else {
if (RevokedJWTDataHolder.isJWTTokenSignatureExistsInRevokedMap(tokenIdentifier)) {
if (log.isDebugEnabled()) {
log.debug("Token retrieved from the revoked jwt token map. Token: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid JWT token. " + GatewayUtils.getMaskedToken(splitToken[0]));
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
}
}
// Not found in cache or caching disabled
if (!isVerified) {
if (log.isDebugEnabled()) {
log.debug("Api Key not found in the cache.");
}
try {
signedJWT = (SignedJWT) JWTParser.parse(apiKey);
payload = signedJWT.getJWTClaimsSet();
} catch (JSONException | IllegalArgumentException | ParseException e) {
if (log.isDebugEnabled()) {
log.debug("Invalid Api Key. Api Key: " + GatewayUtils.getMaskedToken(splitToken[0]), e);
}
log.error("Invalid JWT token. Failed to decode the Api Key body.");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE, e);
}
try {
isVerified = GatewayUtils.verifyTokenSignature(signedJWT, certAlias);
} catch (APISecurityException e) {
if (e.getErrorCode() == APISecurityConstants.API_AUTH_INVALID_CREDENTIALS) {
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
} else {
throw e;
}
}
if (isGatewayTokenCacheEnabled) {
// Add token to tenant token cache
if (isVerified) {
getGatewayApiKeyCache().put(tokenIdentifier, tenantDomain);
} else {
getInvalidGatewayApiKeyCache().put(tokenIdentifier, tenantDomain);
}
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
try {
// Start super tenant flow
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
// Add token to super tenant token cache
if (isVerified) {
getGatewayApiKeyCache().put(tokenIdentifier, tenantDomain);
} else {
getInvalidGatewayApiKeyCache().put(tokenIdentifier, tenantDomain);
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
}
// If Api Key signature is verified
if (isVerified) {
if (log.isDebugEnabled()) {
log.debug("Api Key signature is verified.");
}
if (isGatewayTokenCacheEnabled && payloadInfo != null) {
// Api Key is found in the key cache
payload = payloadInfo.getPayload();
if (isJwtTokenExpired(payload)) {
getGatewayApiKeyCache().remove(tokenIdentifier);
getInvalidGatewayApiKeyCache().put(tokenIdentifier, tenantDomain);
log.error("Api Key is expired");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
validateAPIKeyRestrictions(payload, synCtx);
} else {
// Retrieve payload from ApiKey
if (log.isDebugEnabled()) {
log.debug("ApiKey payload not found in the cache.");
}
if (payload == null) {
try {
signedJWT = (SignedJWT) JWTParser.parse(apiKey);
payload = signedJWT.getJWTClaimsSet();
} catch (JSONException | IllegalArgumentException | ParseException e) {
if (log.isDebugEnabled()) {
log.debug("Invalid ApiKey. ApiKey: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Api Key. Failed to decode the Api Key body.");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE, e);
}
}
if (isJwtTokenExpired(payload)) {
if (isGatewayTokenCacheEnabled) {
getGatewayApiKeyCache().remove(tokenIdentifier);
getInvalidGatewayApiKeyCache().put(tokenIdentifier, tenantDomain);
}
log.error("Api Key is expired");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
validateAPIKeyRestrictions(payload, synCtx);
if (isGatewayTokenCacheEnabled) {
JWTTokenPayloadInfo jwtTokenPayloadInfo = new JWTTokenPayloadInfo();
jwtTokenPayloadInfo.setPayload(payload);
jwtTokenPayloadInfo.setAccessToken(apiKey);
getGatewayApiKeyDataCache().put(cacheKey, jwtTokenPayloadInfo);
}
}
net.minidev.json.JSONObject api = GatewayUtils.validateAPISubscription(apiContext, apiVersion, payload, splitToken, false);
if (log.isDebugEnabled()) {
log.debug("Api Key authentication successful.");
}
String endUserToken = null;
String contextHeader = null;
if (jwtGenerationEnabled) {
SignedJWTInfo signedJWTInfo = new SignedJWTInfo(apiKey, signedJWT, payload);
JWTValidationInfo jwtValidationInfo = getJwtValidationInfo(signedJWTInfo);
JWTInfoDto jwtInfoDto = GatewayUtils.generateJWTInfoDto(api, jwtValidationInfo, null, synCtx);
endUserToken = generateAndRetrieveBackendJWTToken(tokenIdentifier, jwtInfoDto);
contextHeader = getContextHeader();
}
AuthenticationContext authenticationContext;
authenticationContext = GatewayUtils.generateAuthenticationContext(tokenIdentifier, payload, api, getApiLevelPolicy(), endUserToken, synCtx);
APISecurityUtils.setAuthenticationContext(synCtx, authenticationContext, contextHeader);
if (log.isDebugEnabled()) {
log.debug("User is authorized to access the resource using Api Key.");
}
return new AuthenticationResponse(true, isMandatory, false, 0, null);
}
if (log.isDebugEnabled()) {
log.debug("Api Key signature verification failure. Api Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Api Key. Signature verification failed.");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
} catch (APISecurityException e) {
return new AuthenticationResponse(false, isMandatory, true, e.getErrorCode(), e.getMessage());
} catch (ParseException e) {
log.error("Error while parsing API Key", e);
return new AuthenticationResponse(false, isMandatory, true, APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
}
use of io.swagger.v3.oas.annotations.headers.Header in project atlasmap by atlasmap.
the class CsvService method inspect.
/**
* Inspect a CSV instance and return a Document object.
* @param request request
* @param format format
* @param delimiter delimiter
* @param firstRecordAsHeader first record as header
* @param skipHeaderRecord skip header record
* @param headers headers
* @param commentMarker comment marker
* @param escape escape
* @param ignoreEmptyLines ignore empty lines
* @param ignoreHeaderCase ignore header case
* @param ignoreSurroundingSpaces ignore surrounding spaces
* @param nullString null string
* @param quote quote
* @param allowDuplicateHeaderNames allow duplicate header names
* @param allowMissingColumnNames allow missing column names
* @return {@link CsvInspectionResponse}
* @throws IOException unexpected error
*/
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Path("/inspect")
@Operation(summary = "Inspect CSV", description = "Inspect a CSV instance and return a Document object")
@RequestBody(description = "Csv", content = @Content(mediaType = "text/csv", schema = @Schema(implementation = String.class)))
@ApiResponses(@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = CsvInspectionResponse.class)), description = "Return a Document object"))
public Response inspect(InputStream request, @QueryParam("format") String format, @QueryParam("delimiter") String delimiter, @QueryParam("firstRecordAsHeader") Boolean firstRecordAsHeader, @QueryParam("skipRecordHeader") Boolean skipHeaderRecord, @QueryParam("headers") String headers, @QueryParam("commentMarker") String commentMarker, @QueryParam("escape") String escape, @QueryParam("ignoreEmptyLines") Boolean ignoreEmptyLines, @QueryParam("ignoreHeaderCase") Boolean ignoreHeaderCase, @QueryParam("ignoreSurroundingSpaces") Boolean ignoreSurroundingSpaces, @QueryParam("nullString") String nullString, @QueryParam("quote") String quote, @QueryParam("allowDuplicateHeaderNames") Boolean allowDuplicateHeaderNames, @QueryParam("allowMissingColumnNames") Boolean allowMissingColumnNames) throws IOException {
long startTime = System.currentTimeMillis();
CsvInspectionResponse response = new CsvInspectionResponse();
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Options: delimiter={}, firstRecordAsHeader={}", delimiter, firstRecordAsHeader);
}
CsvConfig csvConfig = new CsvConfig(format);
if (delimiter != null) {
csvConfig.setDelimiter(delimiter.charAt(0));
}
csvConfig.setFirstRecordAsHeader(firstRecordAsHeader);
csvConfig.setSkipHeaderRecord(skipHeaderRecord);
csvConfig.setHeaders(headers);
if (commentMarker != null) {
csvConfig.setCommentMarker(commentMarker.charAt(0));
}
if (escape != null) {
csvConfig.setEscape(escape.charAt(0));
}
csvConfig.setIgnoreEmptyLines(ignoreEmptyLines);
csvConfig.setIgnoreHeaderCase(ignoreHeaderCase);
csvConfig.setIgnoreSurroundingSpaces(ignoreSurroundingSpaces);
csvConfig.setNullString(nullString);
if (quote != null) {
csvConfig.setQuote(quote.charAt(0));
}
csvConfig.setAllowDuplicateHeaderNames(allowDuplicateHeaderNames);
csvConfig.setAllowMissingColumnNames(allowMissingColumnNames);
CsvFieldReader csvFieldReader = new CsvFieldReader(csvConfig);
csvFieldReader.setDocument(request);
Document document = csvFieldReader.readSchema();
response.setCsvDocument(document);
request.close();
} catch (Exception e) {
LOG.error("Error inspecting CSV: " + e.getMessage(), e);
response.setErrorMessage(e.getMessage());
} finally {
request.close();
;
response.setExecutionTime(System.currentTimeMillis() - startTime);
}
if (LOG.isDebugEnabled()) {
LOG.debug(("Response: {}" + new ObjectMapper().writeValueAsString(response)));
}
return Response.ok().entity(toJson(response)).build();
}
use of io.swagger.v3.oas.annotations.headers.Header in project carbon-apimgt by wso2.
the class OASParserUtil method setReferenceObjectDefinitions.
private static void setReferenceObjectDefinitions(final OpenAPI destOpenAPI, SwaggerUpdateContext context) {
processReferenceObjectMap(context);
Components components = destOpenAPI.getComponents();
Set<Components> aggregatedComponents = context.getAggregatedComponents();
for (Components sourceComponents : aggregatedComponents) {
Map<String, Set<String>> referenceObjectMap = context.getReferenceObjectMapping();
for (Map.Entry<String, Set<String>> refCategoryEntry : referenceObjectMap.entrySet()) {
String category = refCategoryEntry.getKey();
if (REQUEST_BODIES.equalsIgnoreCase(category)) {
Map<String, RequestBody> sourceRequestBodies = sourceComponents.getRequestBodies();
if (sourceRequestBodies != null) {
for (String refKey : refCategoryEntry.getValue()) {
RequestBody requestBody = sourceRequestBodies.get(refKey);
if (requestBody != null) {
components.addRequestBodies(refKey, requestBody);
}
}
}
}
if (SCHEMAS.equalsIgnoreCase(category)) {
Map<String, Schema> sourceSchemas = sourceComponents.getSchemas();
if (sourceSchemas != null) {
for (String refKey : refCategoryEntry.getValue()) {
Schema schema = sourceSchemas.get(refKey);
if (schema != null) {
components.addSchemas(refKey, schema);
}
}
}
}
if (PARAMETERS.equalsIgnoreCase(category)) {
Map<String, Parameter> parameters = sourceComponents.getParameters();
if (parameters != null) {
for (String refKey : refCategoryEntry.getValue()) {
Parameter parameter = parameters.get(refKey);
if (parameter != null) {
components.addParameters(refKey, parameter);
}
}
}
}
if (RESPONSES.equalsIgnoreCase(category)) {
Map<String, ApiResponse> responses = sourceComponents.getResponses();
if (responses != null) {
for (String refKey : refCategoryEntry.getValue()) {
ApiResponse response = responses.get(refKey);
if (response != null) {
components.addResponses(refKey, response);
}
}
}
}
if (HEADERS.equalsIgnoreCase(category)) {
Map<String, Header> headers = sourceComponents.getHeaders();
if (headers != null) {
for (String refKey : refCategoryEntry.getValue()) {
Header header = headers.get(refKey);
if (header != null) {
components.addHeaders(refKey, header);
}
}
}
}
}
}
}
use of io.swagger.v3.oas.annotations.headers.Header in project carbon-apimgt by wso2.
the class InternalAPIKeyAuthenticator method authenticate.
@Override
public AuthenticationResponse authenticate(MessageContext synCtx) {
API retrievedApi = GatewayUtils.getAPI(synCtx);
if (retrievedApi != null) {
if (log.isDebugEnabled()) {
log.info("Internal Key Authentication initialized");
}
try {
// Extract internal from the request while removing it from the msg context.
String internalKey = extractInternalKey(synCtx);
if (StringUtils.isEmpty(internalKey)) {
return new AuthenticationResponse(false, false, true, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
OpenAPI openAPI = (OpenAPI) synCtx.getProperty(APIMgtGatewayConstants.OPEN_API_OBJECT);
if (openAPI == null && !APIConstants.GRAPHQL_API.equals(synCtx.getProperty(APIConstants.API_TYPE))) {
log.error("Swagger is missing in the gateway. " + "Therefore, Internal Key authentication cannot be performed.");
return new AuthenticationResponse(false, true, false, APISecurityConstants.API_AUTH_MISSING_OPEN_API_DEF, APISecurityConstants.API_AUTH_MISSING_OPEN_API_DEF_ERROR_MESSAGE);
}
JWTTokenPayloadInfo payloadInfo = null;
String[] splitToken = internalKey.split("\\.");
JWTClaimsSet payload;
SignedJWT signedJWT;
String tokenIdentifier;
JWSHeader jwsHeader;
String alias;
if (splitToken.length != 3) {
log.error("Internal Key does not have the format {header}.{payload}.{signature} ");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
signedJWT = SignedJWT.parse(internalKey);
payload = signedJWT.getJWTClaimsSet();
tokenIdentifier = payload.getJWTID();
jwsHeader = signedJWT.getHeader();
if (jwsHeader != null && StringUtils.isNotEmpty(jwsHeader.getKeyID())) {
alias = jwsHeader.getKeyID();
} else {
alias = APIUtil.getInternalApiKeyAlias();
}
// Check if the decoded header contains type as 'InternalKey'.
if (!GatewayUtils.isInternalKey(payload)) {
if (log.isDebugEnabled()) {
log.debug("Invalid Internal Key token type. Internal Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Internal Key token type.");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
String httpMethod = (String) ((Axis2MessageContext) synCtx).getAxis2MessageContext().getProperty(Constants.Configuration.HTTP_METHOD);
String matchingResource = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
String resourceCacheKey = APIUtil.getResourceInfoDTOCacheKey(apiContext, apiVersion, matchingResource, httpMethod);
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setHttpVerb(httpMethod);
// Not doing resource level authentication
verbInfoDTO.setAuthType(APIConstants.AUTH_NO_AUTHENTICATION);
verbInfoDTO.setRequestKey(resourceCacheKey);
verbInfoDTO.setThrottling(OpenAPIUtils.getResourceThrottlingTier(openAPI, synCtx));
List<VerbInfoDTO> verbInfoList = new ArrayList<>();
verbInfoList.add(verbInfoDTO);
synCtx.setProperty(APIConstants.VERB_INFO_DTO, verbInfoList);
String cacheKey = GatewayUtils.getAccessTokenCacheKey(tokenIdentifier, apiContext, apiVersion, matchingResource, httpMethod);
String tenantDomain = GatewayUtils.getTenantDomain();
boolean isVerified = false;
String cacheToken = (String) getGatewayInternalKeyCache().get(tokenIdentifier);
if (cacheToken != null) {
if (log.isDebugEnabled()) {
log.debug("Internal Key retrieved from the Internal Key cache.");
}
if (getGatewayInternalKeyDataCache().get(cacheKey) != null) {
// Token is found in the key cache
payloadInfo = (JWTTokenPayloadInfo) getGatewayInternalKeyDataCache().get(cacheKey);
String accessToken = payloadInfo.getAccessToken();
isVerified = accessToken.equals(internalKey);
}
} else if (getInvalidGatewayInternalKeyCache().get(tokenIdentifier) != null) {
if (log.isDebugEnabled()) {
log.debug("Internal Key retrieved from the invalid Internal Key cache. Internal Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Internal Key." + GatewayUtils.getMaskedToken(splitToken[0]));
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
// Not found in cache or caching disabled
if (!isVerified) {
if (log.isDebugEnabled()) {
log.debug("Internal Key not found in the cache.");
}
isVerified = GatewayUtils.verifyTokenSignature(signedJWT, alias) && !GatewayUtils.isJwtTokenExpired(payload);
// Add token to tenant token cache
if (isVerified) {
getGatewayInternalKeyCache().put(tokenIdentifier, tenantDomain);
} else {
getInvalidGatewayInternalKeyCache().put(tokenIdentifier, tenantDomain);
}
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
try {
// Start super tenant flow
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
// Add token to super tenant token cache
if (isVerified) {
getGatewayInternalKeyCache().put(tokenIdentifier, tenantDomain);
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
// If Internal Key signature is verified
if (isVerified) {
if (log.isDebugEnabled()) {
log.debug("Internal Key signature is verified.");
}
if (payloadInfo != null) {
// Internal Key is found in the key cache
payload = payloadInfo.getPayload();
if (GatewayUtils.isJwtTokenExpired(payload)) {
getGatewayInternalKeyCache().remove(tokenIdentifier);
getInvalidGatewayInternalKeyCache().put(tokenIdentifier, tenantDomain);
log.error("Internal Key is expired");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
} else {
// Retrieve payload from InternalKey
if (log.isDebugEnabled()) {
log.debug("InternalKey payload not found in the cache.");
}
JWTTokenPayloadInfo jwtTokenPayloadInfo = new JWTTokenPayloadInfo();
jwtTokenPayloadInfo.setPayload(payload);
jwtTokenPayloadInfo.setAccessToken(internalKey);
getGatewayInternalKeyDataCache().put(cacheKey, jwtTokenPayloadInfo);
}
JSONObject api = GatewayUtils.validateAPISubscription(apiContext, apiVersion, payload, splitToken, false);
if (log.isDebugEnabled()) {
log.debug("Internal Key authentication successful.");
}
AuthenticationContext authenticationContext = GatewayUtils.generateAuthenticationContext(tokenIdentifier, payload, api, retrievedApi.getApiTier());
APISecurityUtils.setAuthenticationContext(synCtx, authenticationContext);
if (log.isDebugEnabled()) {
log.debug("User is authorized to access the resource using Internal Key.");
}
return new AuthenticationResponse(true, true, false, 0, null);
}
if (log.isDebugEnabled()) {
log.debug("Internal Key signature verification failure. Internal Key: " + GatewayUtils.getMaskedToken(splitToken[0]));
}
log.error("Invalid Internal Key. Signature verification failed.");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
} catch (APISecurityException e) {
return new AuthenticationResponse(false, true, false, e.getErrorCode(), e.getMessage());
} catch (ParseException e) {
log.error("Error while parsing Internal Key", e);
return new AuthenticationResponse(false, true, false, APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
}
return new AuthenticationResponse(false, true, false, APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
Aggregations