use of org.wso2.carbon.apimgt.rest.api.util.MethodStats in project carbon-apimgt by wso2.
the class APIMgtGoogleAnalyticsTrackingHandler method handleRequest.
@MethodStats
@Override
public boolean handleRequest(MessageContext msgCtx) {
TracingSpan span = null;
TracingTracer tracer = null;
Map<String, String> tracerSpecificCarrier = new HashMap<>();
if (Util.tracingEnabled()) {
TracingSpan responseLatencySpan = (TracingSpan) msgCtx.getProperty(APIMgtGatewayConstants.RESOURCE_SPAN);
tracer = Util.getGlobalTracer();
span = Util.startSpan(APIMgtGatewayConstants.GOOGLE_ANALYTICS_HANDLER, responseLatencySpan, tracer);
}
try {
if (configKey == null) {
throw new SynapseException("Google Analytics configuration unspecified for the API");
}
Entry entry = msgCtx.getConfiguration().getEntryDefinition(configKey);
if (entry == null) {
log.warn("Cannot find Google Analytics configuration using key: " + configKey);
return true;
}
Object entryValue = null;
boolean reCreate = false;
if (entry.isDynamic()) {
if ((!entry.isCached()) || (entry.isExpired()) || config == null) {
entryValue = msgCtx.getEntry(this.configKey);
if (this.version != entry.getVersion()) {
reCreate = true;
}
}
} else if (config == null) {
entryValue = msgCtx.getEntry(this.configKey);
}
if (reCreate || config == null) {
if (entryValue == null || !(entryValue instanceof OMElement)) {
log.warn("Unable to load Google Analytics configuration using key: " + configKey);
return true;
}
version = entry.getVersion();
config = getGoogleAnalyticsConfig((OMElement) entryValue);
}
if (config == null) {
log.warn("Unable to create Google Analytics configuration using key: " + configKey);
return true;
}
if (!config.isEnabled()) {
return true;
}
try {
if (Util.tracingEnabled()) {
Util.inject(span, tracer, tracerSpecificCarrier);
if (org.apache.axis2.context.MessageContext.getCurrentMessageContext() != null) {
Map headers = (Map) org.apache.axis2.context.MessageContext.getCurrentMessageContext().getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
headers.putAll(tracerSpecificCarrier);
org.apache.axis2.context.MessageContext.getCurrentMessageContext().setProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS, headers);
}
}
trackPageView(msgCtx);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return true;
} catch (Exception e) {
if (Util.tracingEnabled() && span != null) {
Util.setTag(span, APIMgtGatewayConstants.ERROR, APIMgtGatewayConstants.GOOGLE_ANALYTICS_ERROR);
}
throw e;
} finally {
if (Util.tracingEnabled()) {
Util.finishSpan(span);
}
}
}
use of org.wso2.carbon.apimgt.rest.api.util.MethodStats in project carbon-apimgt by wso2.
the class OAuthAuthenticator method authenticate.
@MethodStats
public AuthenticationResponse authenticate(MessageContext synCtx) throws APIManagementException {
boolean isJwtToken = false;
String accessToken = null;
String remainingAuthHeader = "";
boolean defaultVersionInvoked = false;
Map headers = (Map) ((Axis2MessageContext) synCtx).getAxis2MessageContext().getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
String tenantDomain = GatewayUtils.getTenantDomain();
keyManagerList = GatewayUtils.getKeyManagers(synCtx);
if (keyValidator == null) {
this.keyValidator = new APIKeyValidator();
}
if (jwtValidator == null) {
this.jwtValidator = new JWTValidator(this.keyValidator, tenantDomain);
}
config = getApiManagerConfiguration();
removeOAuthHeadersFromOutMessage = isRemoveOAuthHeadersFromOutMessage();
securityContextHeader = getSecurityContextHeader();
if (headers != null) {
requestOrigin = (String) headers.get("Origin");
// Extract the access token from auth header
// From 1.0.7 version of this component onwards remove the OAuth authorization header from
// the message is configurable. So we dont need to remove headers at this point.
String authHeader = (String) headers.get(getSecurityHeader());
if (authHeader == null) {
if (log.isDebugEnabled()) {
log.debug("OAuth2 Authentication: Expected authorization header with the name '".concat(getSecurityHeader()).concat("' was not found."));
}
} else {
ArrayList<String> remainingAuthHeaders = new ArrayList<>();
boolean consumerkeyFound = false;
String[] splitHeaders = authHeader.split(oauthHeaderSplitter);
if (splitHeaders != null) {
for (int i = 0; i < splitHeaders.length; i++) {
String[] elements = splitHeaders[i].split(consumerKeySegmentDelimiter);
if (elements != null && elements.length > 1) {
int j = 0;
boolean isConsumerKeyHeaderAvailable = false;
for (String element : elements) {
if (!"".equals(element.trim())) {
if (consumerKeyHeaderSegment.equals(elements[j].trim())) {
isConsumerKeyHeaderAvailable = true;
} else if (isConsumerKeyHeaderAvailable) {
accessToken = removeLeadingAndTrailing(elements[j].trim());
consumerkeyFound = true;
}
}
j++;
}
}
if (!consumerkeyFound) {
remainingAuthHeaders.add(splitHeaders[i]);
} else {
consumerkeyFound = false;
}
}
}
remainingAuthHeader = String.join(oauthHeaderSplitter, remainingAuthHeaders);
}
if (log.isDebugEnabled()) {
log.debug(accessToken != null ? "Received Token ".concat(accessToken) : "No valid Authorization header found");
}
// Check if client invoked the default version API (accessing API without version).
defaultVersionInvoked = headers.containsKey(defaultAPIHeader);
}
if (log.isDebugEnabled()) {
log.debug("Default Version API invoked");
}
if (removeOAuthHeadersFromOutMessage) {
// Remove authorization headers sent for authentication at the gateway and pass others to the backend
if (StringUtils.isNotBlank(remainingAuthHeader)) {
if (log.isDebugEnabled()) {
log.debug("Removing OAuth key from Authorization header");
}
headers.put(getSecurityHeader(), remainingAuthHeader);
} else {
if (log.isDebugEnabled()) {
log.debug("Removing Authorization header from headers");
}
headers.remove(getSecurityHeader());
}
}
if (removeDefaultAPIHeaderFromOutMessage) {
headers.remove(defaultAPIHeader);
}
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);
SignedJWTInfo signedJWTInfo = null;
// If the matching resource does not require authentication
Timer timer = getTimer(MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "GET_RESOURCE_AUTH"));
Timer.Context context = timer.start();
org.apache.axis2.context.MessageContext axis2MessageCtx = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
org.apache.axis2.context.MessageContext.setCurrentMessageContext(axis2MessageCtx);
String authenticationScheme;
try {
// Initial guess of a JWT token using the presence of a DOT.
if (StringUtils.isNotEmpty(accessToken) && accessToken.contains(APIConstants.DOT)) {
try {
if (StringUtils.countMatches(accessToken, APIConstants.DOT) != 2) {
log.debug("Invalid JWT token. The expected token format is <header.payload.signature>");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
}
signedJWTInfo = getSignedJwt(accessToken);
if (GatewayUtils.isInternalKey(signedJWTInfo.getJwtClaimsSet()) || GatewayUtils.isAPIKey(signedJWTInfo.getJwtClaimsSet())) {
log.debug("Invalid Token Provided");
return new AuthenticationResponse(false, isMandatory, true, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
String keyManager = ServiceReferenceHolder.getInstance().getJwtValidationService().getKeyManagerNameIfJwtValidatorExist(signedJWTInfo);
if (StringUtils.isNotEmpty(keyManager)) {
if (log.isDebugEnabled()) {
log.debug("KeyManager " + keyManager + "found for authenticate token " + GatewayUtils.getMaskedToken(accessToken));
}
if (keyManagerList.contains(APIConstants.KeyManager.API_LEVEL_ALL_KEY_MANAGERS) || keyManagerList.contains(keyManager)) {
if (log.isDebugEnabled()) {
log.debug("Elected KeyManager " + keyManager + "found in API level list " + String.join(",", keyManagerList));
}
isJwtToken = true;
} else {
if (log.isDebugEnabled()) {
log.debug("Elected KeyManager " + keyManager + " not found in API level list " + String.join(",", keyManagerList));
}
return new AuthenticationResponse(false, isMandatory, true, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
} else {
if (log.isDebugEnabled()) {
log.debug("KeyManager not found for accessToken " + GatewayUtils.getMaskedToken(accessToken));
}
}
} catch (ParseException | IllegalArgumentException e) {
log.debug("Not a JWT token. Failed to decode the token header.", e);
} catch (APIManagementException e) {
log.error("error while check validation of JWt", e);
return new AuthenticationResponse(false, isMandatory, true, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
}
authenticationScheme = getAPIKeyValidator().getResourceAuthenticationScheme(synCtx);
} catch (APISecurityException ex) {
return new AuthenticationResponse(false, isMandatory, true, ex.getErrorCode(), ex.getMessage());
}
context.stop();
APIKeyValidationInfoDTO info;
if (APIConstants.NO_MATCHING_AUTH_SCHEME.equals(authenticationScheme)) {
info = new APIKeyValidationInfoDTO();
info.setAuthorized(false);
info.setValidationStatus(900906);
} else if (accessToken == null || apiContext == null || apiVersion == null) {
if (log.isDebugEnabled()) {
if (accessToken == null) {
log.debug("OAuth headers not found");
} else if (apiContext == null) {
log.debug("Couldn't find API Context");
} else {
log.debug("Could not find api version");
}
}
return new AuthenticationResponse(false, isMandatory, true, APISecurityConstants.API_AUTH_MISSING_CREDENTIALS, "Required OAuth credentials not provided");
} else {
// Start JWT token validation
if (isJwtToken) {
try {
AuthenticationContext authenticationContext = jwtValidator.authenticate(signedJWTInfo, synCtx);
APISecurityUtils.setAuthenticationContext(synCtx, authenticationContext, securityContextHeader);
log.debug("User is authorized using JWT token to access the resource.");
synCtx.setProperty(APIMgtGatewayConstants.END_USER_NAME, authenticationContext.getUsername());
return new AuthenticationResponse(true, isMandatory, false, 0, null);
} catch (APISecurityException ex) {
return new AuthenticationResponse(false, isMandatory, true, ex.getErrorCode(), ex.getMessage());
}
}
if (log.isDebugEnabled()) {
log.debug("Matching resource is: ".concat(matchingResource));
}
timer = getTimer(MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "GET_KEY_VALIDATION_INFO"));
context = timer.start();
try {
info = getAPIKeyValidator().getKeyValidationInfo(apiContext, accessToken, apiVersion, authenticationScheme, matchingResource, httpMethod, defaultVersionInvoked, keyManagerList);
} catch (APISecurityException ex) {
return new AuthenticationResponse(false, isMandatory, true, ex.getErrorCode(), ex.getMessage());
}
context.stop();
synCtx.setProperty(APIMgtGatewayConstants.APPLICATION_NAME, info.getApplicationName());
synCtx.setProperty(APIMgtGatewayConstants.END_USER_NAME, info.getEndUserName());
synCtx.setProperty(APIMgtGatewayConstants.SCOPES, info.getScopes() == null ? null : info.getScopes().toString());
}
if (info.isAuthorized()) {
AuthenticationContext authContext = new AuthenticationContext();
authContext.setAuthenticated(true);
authContext.setTier(info.getTier());
authContext.setApiKey(accessToken);
authContext.setKeyType(info.getType());
if (info.getEndUserName() != null) {
authContext.setUsername(info.getEndUserName());
} else {
authContext.setUsername(APIConstants.END_USER_ANONYMOUS);
}
authContext.setCallerToken(info.getEndUserToken());
authContext.setApplicationId(info.getApplicationId());
authContext.setApplicationUUID(info.getApplicationUUID());
authContext.setApplicationName(info.getApplicationName());
authContext.setApplicationTier(info.getApplicationTier());
authContext.setSubscriber(info.getSubscriber());
authContext.setConsumerKey(info.getConsumerKey());
authContext.setApiTier(info.getApiTier());
authContext.setThrottlingDataList(info.getThrottlingDataList());
authContext.setSubscriberTenantDomain(info.getSubscriberTenantDomain());
authContext.setSpikeArrestLimit(info.getSpikeArrestLimit());
authContext.setSpikeArrestUnit(info.getSpikeArrestUnit());
authContext.setStopOnQuotaReach(info.isStopOnQuotaReach());
authContext.setIsContentAware(info.isContentAware());
APISecurityUtils.setAuthenticationContext(synCtx, authContext, securityContextHeader);
if (info.getProductName() != null && info.getProductProvider() != null) {
authContext.setProductName(info.getProductName());
authContext.setProductProvider(info.getProductProvider());
}
/* Synapse properties required for BAM Mediator*/
// String tenantDomain = MultitenantUtils.getTenantDomain(info.getApiPublisher());
synCtx.setProperty("api.ut.apiPublisher", info.getApiPublisher());
synCtx.setProperty("API_NAME", info.getApiName());
/* GraphQL Query Analysis Information */
if (APIConstants.GRAPHQL_API.equals(synCtx.getProperty(APIConstants.API_TYPE))) {
synCtx.setProperty(APIConstants.MAXIMUM_QUERY_DEPTH, info.getGraphQLMaxDepth());
synCtx.setProperty(APIConstants.MAXIMUM_QUERY_COMPLEXITY, info.getGraphQLMaxComplexity());
}
if (log.isDebugEnabled()) {
log.debug("User is authorized to access the Resource");
}
return new AuthenticationResponse(true, isMandatory, false, 0, null);
} else {
if (log.isDebugEnabled()) {
log.debug("User is NOT authorized to access the Resource");
}
return new AuthenticationResponse(false, isMandatory, true, info.getValidationStatus(), "Access failure for API: " + apiContext + ", version: " + apiVersion + " status: (" + info.getValidationStatus() + ") - " + APISecurityConstants.getAuthenticationFailureMessage(info.getValidationStatus()));
}
}
use of org.wso2.carbon.apimgt.rest.api.util.MethodStats in project carbon-apimgt by wso2.
the class BasicAuthCredentialValidator method validateScopes.
/**
* Validates the roles of the given user against the roles of the scopes of the API resource.
*
* @param username given username
* @param openAPI OpenAPI of the API
* @param synCtx The message to be authenticated
* @param userRoleList The list of roles of the user
* @return true if the validation passed
* @throws APISecurityException If an authentication failure or some other error occurs
*/
@MethodStats
public boolean validateScopes(String username, OpenAPI openAPI, MessageContext synCtx, BasicAuthValidationInfoDTO basicAuthValidationInfoDTO) throws APISecurityException {
String[] userRoleList = basicAuthValidationInfoDTO.getUserRoleList();
String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
String apiElectedResource = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
String httpMethod = (String) axis2MessageContext.getProperty(APIConstants.DigestAuthConstants.HTTP_METHOD);
String resourceKey = apiContext + ":" + apiVersion + ":" + apiElectedResource + ":" + httpMethod;
Map<String, Scope> scopeMap = apiKeyValidator.retrieveScopes(tenantDomain);
String resourceCacheKey = resourceKey + ":" + username;
if (gatewayKeyCacheEnabled && getGatewayBasicAuthResourceCache().get(resourceCacheKey) != null && basicAuthValidationInfoDTO.isCached()) {
return true;
}
if (openAPI != null) {
// retrieve the user roles related to the scope of the API resource
List<String> resourceScopes = OpenAPIUtils.getScopesOfResource(openAPI, synCtx);
if (resourceScopes != null && resourceScopes.size() > 0) {
for (String resourceScope : resourceScopes) {
Scope scope = scopeMap.get(resourceScope);
if (scope != null) {
if (scope.getRoles().isEmpty()) {
log.debug("Scope " + resourceScope + " didn't have roles");
if (gatewayKeyCacheEnabled) {
getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
}
return true;
} else {
// any of the role of the user
if (validateInternalUserRoles(scope.getRoles(), userRoleList)) {
if (gatewayKeyCacheEnabled) {
getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
}
return true;
}
// check if the roles related to the API resource contains any of the role of the user
for (String role : userRoleList) {
if (scope.getRoles().contains(role)) {
if (gatewayKeyCacheEnabled) {
getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
}
return true;
}
}
}
}
}
} else {
if (log.isDebugEnabled()) {
log.debug("Basic Authentication: No scopes for the API resource: ".concat(resourceKey));
}
return true;
}
} else if (APIConstants.GRAPHQL_API.equals(synCtx.getProperty(APIConstants.API_TYPE))) {
HashMap<String, String> operationScopeMappingList = (HashMap<String, String>) synCtx.getProperty(APIConstants.SCOPE_OPERATION_MAPPING);
String[] operationList = ((String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE)).split(",");
for (String operation : operationList) {
String operationScope = operationScopeMappingList.get(operation);
if (operationScope != null) {
if (scopeMap.containsKey(operationScope)) {
List<String> operationRoles = scopeMap.get(operationScope).getRoles();
boolean userHasOperationRole = false;
if (operationRoles.isEmpty()) {
userHasOperationRole = true;
} else {
for (String role : userRoleList) {
if (operationRoles.contains(role)) {
userHasOperationRole = true;
break;
}
}
}
if (!userHasOperationRole) {
throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, "Scope validation failed");
}
} else {
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
}
}
if (gatewayKeyCacheEnabled) {
getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
}
return true;
} else {
if (log.isDebugEnabled()) {
log.debug("Basic Authentication: No OpenAPI found in the gateway for the API: ".concat(apiContext).concat(":").concat(apiVersion));
}
return true;
}
if (log.isDebugEnabled()) {
log.debug("Basic Authentication: Scope validation failed for the API resource: ".concat(apiElectedResource));
}
throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, "Scope validation failed");
}
use of org.wso2.carbon.apimgt.rest.api.util.MethodStats in project carbon-apimgt by wso2.
the class BasicAuthCredentialValidator method validate.
/**
* Validates the given username and password against the users in the user store.
*
* @param username given username
* @param password given password
* @return true if the validation passed
* @throws APISecurityException If an authentication failure or some other error occurs
*/
@MethodStats
public BasicAuthValidationInfoDTO validate(String username, String password) throws APISecurityException {
boolean isAuthenticated;
String cachedPasswordHash = null;
String providedPasswordHash = null;
String invalidCachedPasswordHash;
if (gatewayKeyCacheEnabled) {
providedPasswordHash = GatewayUtils.hashString(password.getBytes(StandardCharsets.UTF_8));
BasicAuthValidationInfoDTO cachedValidationInfoObj = (BasicAuthValidationInfoDTO) getGatewayUsernameCache().get(username);
if (cachedValidationInfoObj != null) {
cachedPasswordHash = cachedValidationInfoObj.getHashedPassword();
cachedValidationInfoObj.setCached(true);
}
if (cachedPasswordHash != null && cachedPasswordHash.equals(providedPasswordHash)) {
log.debug("Basic Authentication: <Valid Username Cache> Username & password authenticated");
return cachedValidationInfoObj;
} else {
BasicAuthValidationInfoDTO invalidCacheValidationInfoObj = (BasicAuthValidationInfoDTO) getInvalidUsernameCache().get(username);
if (invalidCacheValidationInfoObj != null) {
invalidCacheValidationInfoObj.setCached(true);
invalidCachedPasswordHash = invalidCacheValidationInfoObj.getHashedPassword();
if (invalidCachedPasswordHash != null && invalidCachedPasswordHash.equals(providedPasswordHash)) {
log.debug("Basic Authentication: <Invalid Username Cache> Username & password authentication failed");
invalidCacheValidationInfoObj.setAuthenticated(// If (username->password) is in the invalid cache
false);
return invalidCacheValidationInfoObj;
}
}
}
}
BasicAuthValidationInfoDTO basicAuthValidationInfoDTO;
try {
org.wso2.carbon.apimgt.impl.dto.xsd.BasicAuthValidationInfoDTO generatedInfoDTO = apiKeyMgtRemoteUserStoreMgtServiceStub.getUserAuthenticationInfo(username, password);
basicAuthValidationInfoDTO = convertToDTO(generatedInfoDTO);
isAuthenticated = basicAuthValidationInfoDTO.isAuthenticated();
} catch (APIKeyMgtRemoteUserStoreMgtServiceAPIManagementException | RemoteException e) {
log.error("Basic Authentication: Error while accessing backend services to validate user authentication for user : " + username);
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, e.getMessage(), e);
}
if (gatewayKeyCacheEnabled) {
basicAuthValidationInfoDTO.setHashedPassword(providedPasswordHash);
if (isAuthenticated) {
// put (username->password) into the valid cache
getGatewayUsernameCache().put(username, basicAuthValidationInfoDTO);
} else {
// put (username->password) into the invalid cache
getInvalidUsernameCache().put(username, basicAuthValidationInfoDTO);
}
}
return basicAuthValidationInfoDTO;
}
use of org.wso2.carbon.apimgt.rest.api.util.MethodStats in project carbon-apimgt by wso2.
the class JWTValidator method authenticate.
/**
* Authenticates the given request with a JWT token to see if an API consumer is allowed to access
* a particular API or not.
*
* @param signedJWTInfo The JWT token sent with the API request
* @param synCtx The message to be authenticated
* @return an AuthenticationContext object which contains the authentication information
* @throws APISecurityException in case of authentication failure
*/
@MethodStats
public AuthenticationContext authenticate(SignedJWTInfo signedJWTInfo, MessageContext synCtx) throws APISecurityException {
String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
org.apache.axis2.context.MessageContext axis2MsgContext = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
String httpMethod = (String) axis2MsgContext.getProperty(Constants.Configuration.HTTP_METHOD);
String matchingResource = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
String jwtTokenIdentifier = getJWTTokenIdentifier(signedJWTInfo);
String jwtHeader = signedJWTInfo.getSignedJWT().getHeader().toString();
try {
X509Certificate clientCertificate = Utils.getClientCertificate(axis2MsgContext);
signedJWTInfo.setX509ClientCertificate(clientCertificate);
} catch (APIManagementException e) {
log.error("Error while obtaining client certificate. " + GatewayUtils.getMaskedToken(jwtHeader));
}
if (StringUtils.isNotEmpty(jwtTokenIdentifier)) {
if (RevokedJWTDataHolder.isJWTTokenSignatureExistsInRevokedMap(jwtTokenIdentifier)) {
if (log.isDebugEnabled()) {
log.debug("Token retrieved from the revoked jwt token map. Token: " + GatewayUtils.getMaskedToken(jwtHeader));
}
log.error("Invalid JWT token. " + GatewayUtils.getMaskedToken(jwtHeader));
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
}
}
JWTValidationInfo jwtValidationInfo = getJwtValidationInfo(signedJWTInfo, jwtTokenIdentifier);
if (jwtValidationInfo != null) {
if (jwtValidationInfo.isValid()) {
// Validate subscriptions
APIKeyValidationInfoDTO apiKeyValidationInfoDTO;
log.debug("Begin subscription validation via Key Manager: " + jwtValidationInfo.getKeyManager());
apiKeyValidationInfoDTO = validateSubscriptionUsingKeyManager(synCtx, jwtValidationInfo);
if (log.isDebugEnabled()) {
log.debug("Subscription validation via Key Manager. Status: " + apiKeyValidationInfoDTO.isAuthorized());
}
if (!apiKeyValidationInfoDTO.isAuthorized()) {
log.debug("User is NOT authorized to access the Resource. API Subscription validation failed.");
throw new APISecurityException(apiKeyValidationInfoDTO.getValidationStatus(), "User is NOT authorized to access the Resource. API Subscription validation failed.");
}
// Validate scopes
validateScopes(apiContext, apiVersion, matchingResource, httpMethod, jwtValidationInfo, signedJWTInfo);
synCtx.setProperty(APIMgtGatewayConstants.SCOPES, jwtValidationInfo.getScopes().toString());
if (apiKeyValidationInfoDTO.isAuthorized()) {
/*
* Set api.ut.apiPublisher of the subscribed api to the message context.
* This is necessary for the functionality of Publisher alerts.
* Set API_NAME of the subscribed api to the message context.
* */
synCtx.setProperty(APIMgtGatewayConstants.API_PUBLISHER, apiKeyValidationInfoDTO.getApiPublisher());
synCtx.setProperty("API_NAME", apiKeyValidationInfoDTO.getApiName());
/* GraphQL Query Analysis Information */
if (APIConstants.GRAPHQL_API.equals(synCtx.getProperty(APIConstants.API_TYPE))) {
synCtx.setProperty(APIConstants.MAXIMUM_QUERY_DEPTH, apiKeyValidationInfoDTO.getGraphQLMaxDepth());
synCtx.setProperty(APIConstants.MAXIMUM_QUERY_COMPLEXITY, apiKeyValidationInfoDTO.getGraphQLMaxComplexity());
}
log.debug("JWT authentication successful.");
}
log.debug("JWT authentication successful.");
String endUserToken = null;
if (jwtGenerationEnabled) {
JWTInfoDto jwtInfoDto = GatewayUtils.generateJWTInfoDto(null, jwtValidationInfo, apiKeyValidationInfoDTO, synCtx);
endUserToken = generateAndRetrieveJWTToken(jwtTokenIdentifier, jwtInfoDto);
}
return GatewayUtils.generateAuthenticationContext(jwtTokenIdentifier, jwtValidationInfo, apiKeyValidationInfoDTO, endUserToken, true);
} else {
throw new APISecurityException(jwtValidationInfo.getValidationCode(), APISecurityConstants.getAuthenticationFailureMessage(jwtValidationInfo.getValidationCode()));
}
} else {
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
}
Aggregations