use of org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo 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.impl.jwt.SignedJWTInfo 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 org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo in project carbon-apimgt by wso2.
the class ApiKeyAuthenticator method getJwtValidationInfo.
private JWTValidationInfo getJwtValidationInfo(SignedJWTInfo signedJWTInfo) {
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setClaims(new HashMap<>(signedJWTInfo.getJwtClaimsSet().getClaims()));
jwtValidationInfo.setUser(signedJWTInfo.getJwtClaimsSet().getSubject());
return jwtValidationInfo;
}
use of org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo in project carbon-apimgt by wso2.
the class JWTValidator method authenticateForGraphQLSubscription.
/**
* Authenticate for GraphQL subscriptions API requests. This method validates the token signature, expire time and
* subscription. The token request scopes are added to the AuthenticationContxt to validate later.
*
* @param signedJWTInfo SignedJWTInfo
* @param apiContext API context
* @param apiVersion API version
* @return AuthenticationContext
* @throws APISecurityException if an error occurs
*/
public AuthenticationContext authenticateForGraphQLSubscription(SignedJWTInfo signedJWTInfo, String apiContext, String apiVersion) throws APISecurityException {
String tokenSignature = signedJWTInfo.getSignedJWT().getSignature().toString();
JWTClaimsSet jwtClaimsSet = signedJWTInfo.getJwtClaimsSet();
String jti = jwtClaimsSet.getJWTID();
JWTValidationInfo jwtValidationInfo = validateTokenForWS(signedJWTInfo, tokenSignature, jti);
if (jwtValidationInfo != null && jwtValidationInfo.isValid()) {
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = validateSubscriptionsForWS(jwtValidationInfo, apiContext, apiVersion);
if (apiKeyValidationInfoDTO.isAuthorized()) {
if (log.isDebugEnabled()) {
log.debug("JWT authentication successful. user: " + apiKeyValidationInfoDTO.getEndUserName());
}
String endUserToken = generateBackendJWTForWS(jwtValidationInfo, apiKeyValidationInfoDTO, apiContext, apiVersion, tokenSignature);
return generateAuthenticationContextForWS(jti, jwtValidationInfo, apiKeyValidationInfoDTO, endUserToken, apiVersion);
} else {
String message = "User is NOT authorized to access the Resource. API Subscription validation failed.";
log.error(message);
throw new APISecurityException(apiKeyValidationInfoDTO.getValidationStatus(), message);
}
} else if (!jwtValidationInfo.isValid()) {
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
}
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
use of org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo in project carbon-apimgt by wso2.
the class JWTValidator method getJwtValidationInfo.
private JWTValidationInfo getJwtValidationInfo(SignedJWTInfo signedJWTInfo, String jti) throws APISecurityException {
String jwtHeader = signedJWTInfo.getSignedJWT().getHeader().toString();
String tenantDomain = GatewayUtils.getTenantDomain();
JWTValidationInfo jwtValidationInfo = null;
if (isGatewayTokenCacheEnabled && !SignedJWTInfo.ValidationStatus.NOT_VALIDATED.equals(signedJWTInfo.getValidationStatus())) {
String cacheToken = (String) getGatewayTokenCache().get(jti);
if (SignedJWTInfo.ValidationStatus.VALID.equals(signedJWTInfo.getValidationStatus()) && cacheToken != null) {
if (getGatewayKeyCache().get(jti) != null) {
JWTValidationInfo tempJWTValidationInfo = (JWTValidationInfo) getGatewayKeyCache().get(jti);
checkTokenExpiration(jti, tempJWTValidationInfo, tenantDomain);
jwtValidationInfo = tempJWTValidationInfo;
}
} else if (SignedJWTInfo.ValidationStatus.INVALID.equals(signedJWTInfo.getValidationStatus()) && getInvalidTokenCache().get(jti) != null) {
if (log.isDebugEnabled()) {
log.debug("Token retrieved from the invalid token cache. Token: " + GatewayUtils.getMaskedToken(jwtHeader));
}
log.error("Invalid JWT token. " + GatewayUtils.getMaskedToken(jwtHeader));
jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValidationCode(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS);
jwtValidationInfo.setValid(false);
}
}
if (jwtValidationInfo == null) {
try {
jwtValidationInfo = jwtValidationService.validateJWTToken(signedJWTInfo);
signedJWTInfo.setValidationStatus(jwtValidationInfo.isValid() ? SignedJWTInfo.ValidationStatus.VALID : SignedJWTInfo.ValidationStatus.INVALID);
if (isGatewayTokenCacheEnabled) {
// Add token to tenant token cache
if (jwtValidationInfo.isValid()) {
getGatewayTokenCache().put(jti, tenantDomain);
getGatewayKeyCache().put(jti, jwtValidationInfo);
} else {
getInvalidTokenCache().put(jti, tenantDomain);
}
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
// to remove the entry when the need occurs to clear this particular cache entry.
try {
// Start super tenant flow
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
// Add token to super tenant token cache
if (jwtValidationInfo.isValid()) {
getGatewayTokenCache().put(jti, tenantDomain);
} else {
getInvalidTokenCache().put(jti, tenantDomain);
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
return jwtValidationInfo;
} catch (APIManagementException e) {
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
}
return jwtValidationInfo;
}
Aggregations