diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java index 752400985132..1245f98457ff 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java @@ -427,7 +427,7 @@ private String generateAndRetrieveJWTToken(String tokenSignature, JWTInfoDto jwt return endUserToken; } - private void includeUserStoreClaimsIntoClaims(JWTInfoDto jwtInfoDto) { + private void includeUserStoreClaimsIntoClaims(JWTInfoDto jwtInfoDto) throws JWTGeneratorException { JWTInfoDto localJWTInfoDto = new JWTInfoDto(jwtInfoDto); Map userClaimsFromKeyManager = getUserClaimsFromKeyManager(localJWTInfoDto); @@ -859,7 +859,7 @@ protected Cache getGatewayJWTTokenCache() { return CacheProvider.getGatewayJWTTokenCache(); } - private Map getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) { + private Map getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) throws JWTGeneratorException { if (jwtConfigurationDto.isEnableUserClaimRetrievalFromUserStore()) { String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); @@ -881,7 +881,11 @@ private Map getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) { try { return keyManagerInstance.getUserClaims(jwtInfoDto.getEndUser(), properties); } catch (APIManagementException e) { - log.error("Error while retrieving User claims from Key Manager ", e); + if (jwtConfigurationDto.isContinueOnClaimRetrievalFailure()) { + log.error("Error while retrieving User Claims from Key Manager ", e); + } else { + throw new JWTGeneratorException("Error while retrieving User Claims from Key Manager", e); + } } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/APIKeyValidatorClient.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/APIKeyValidatorClient.java index 87d71ac2a1ed..7843b4463ea2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/APIKeyValidatorClient.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/APIKeyValidatorClient.java @@ -56,7 +56,7 @@ public APIKeyValidationInfoDTO getAPIKeyData(String context, String apiVersion, } catch (APIKeyMgtException | APIManagementException e) { log.error("Error while retrieving data from datastore", e); throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, - "Error while retrieving data from datastore", e); + e.getMessage(), e); } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/WSAPIKeyDataStore.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/WSAPIKeyDataStore.java index 3efc29661240..75b510966b3e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/WSAPIKeyDataStore.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/keys/WSAPIKeyDataStore.java @@ -22,6 +22,7 @@ import org.wso2.carbon.apimgt.gateway.MethodStats; import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityConstants; import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException; +import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO; import org.wso2.carbon.apimgt.keymgt.model.entity.Scope; import org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext; @@ -53,6 +54,10 @@ public APIKeyValidationInfoDTO getAPIKeyData(String context, String apiVersion, return client.getAPIKeyData(context, apiVersion, apiKey, requiredAuthenticationLevel, matchingResource, httpVerb, tenantDomain, keyManagers); } catch (APISecurityException ex) { + if (ex.getMessage().equalsIgnoreCase(APIConstants.JWT_GENERATION_ERROR)) { + throw new APISecurityException(ex.getErrorCode(), + APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE, ex); + } throw new APISecurityException(ex.getErrorCode(), "Resource forbidden", ex); } catch (Exception e) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index fb9641c1895f..12d0e9f0c6df 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -676,6 +676,7 @@ private AI() { public static final String VALUE = "value"; public static final String GATEWAY_INTROSPECT_CACHE_NAME = "GatewayIntrospectCache"; public static final String ENABLE_USER_CLAIMS_RETRIEVAL_FROM_KEY_MANAGER = "EnableUserClaimRetrievalFromKeyManager"; + public static final String CONTINUE_ON_CLAIM_RETRIEVAL_FAILURE = "ContinueOnClaimRetrievalFailure"; public static final String DELEM_COLON = ":"; public static final String DELEM_COMMA = ","; @@ -1912,6 +1913,8 @@ public enum RegistryResourceTypesForUI { public static final String MSG_TIER_RET_ERROR = "Error while retrieving API tiers from registry"; public static final String MSG_MALFORMED_XML_ERROR = "Malformed XML found in the API tier policy resource"; + public static final String JWT_GENERATION_ERROR = "Error occurred while generating JWT"; + //Doc search related constants public static final String PUBLISHER_CLIENT = "Publisher"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java index 17059fa03d66..0b0d9814af97 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java @@ -1845,6 +1845,12 @@ private void setJWTConfiguration(OMElement omElement) { } } } + OMElement continueOnCustomClaimRetrievalFailureElement = + omElement.getFirstChildWithName(new QName(APIConstants.CONTINUE_ON_CLAIM_RETRIEVAL_FAILURE)); + if (continueOnCustomClaimRetrievalFailureElement != null) { + jwtConfigurationDto.setContinueOnClaimRetrievalFailure( + Boolean.parseBoolean(continueOnCustomClaimRetrievalFailureElement.getText())); + } OMElement enableBase64PaddingElement = gatewayJWTConfigurationElement.getFirstChildWithName( new QName(APIConstants.ENABLE_BASE64_PADDING)); if (enableBase64PaddingElement != null) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dto/ExtendedJWTConfigurationDto.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dto/ExtendedJWTConfigurationDto.java index 285b2a12b30e..6cd69b90d20f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dto/ExtendedJWTConfigurationDto.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dto/ExtendedJWTConfigurationDto.java @@ -6,6 +6,7 @@ public class ExtendedJWTConfigurationDto extends JWTConfigurationDto { private String jwtGeneratorImplClass = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"; private String claimRetrieverImplClass; private boolean tenantBasedSigningEnabled; + private boolean continueOnClaimRetrievalFailure; private boolean enableUserClaimRetrievalFromUserStore; private boolean isBindFederatedUserClaims; private boolean isJWKSApiEnabled; @@ -50,6 +51,14 @@ public boolean isEnableUserClaimRetrievalFromUserStore() { return enableUserClaimRetrievalFromUserStore; } + public boolean isContinueOnClaimRetrievalFailure() { + return continueOnClaimRetrievalFailure; + } + + public void setContinueOnClaimRetrievalFailure(boolean continueOnClaimRetrievalFailure) { + this.continueOnClaimRetrievalFailure = continueOnClaimRetrievalFailure; + } + public boolean isBindFederatedUserClaims() { return isBindFederatedUserClaims; diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/AbstractKeyValidationHandler.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/AbstractKeyValidationHandler.java index 72b7fc1321ba..f7354c9bd8b2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/AbstractKeyValidationHandler.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/AbstractKeyValidationHandler.java @@ -133,17 +133,19 @@ protected boolean hasTokenRequiredAuthLevel(String authScheme, @Override public boolean generateConsumerToken(TokenValidationContext validationContext) throws APIKeyMgtException { - + String jwt = null; try { - String jwt = getCachedJWTToken(validationContext); - validationContext.getValidationInfoDTO().setEndUserToken(jwt); - return true; - + jwt = getCachedJWTToken(validationContext); } catch (APIManagementException e) { - log.error("Error occurred while generating JWT. ", e); + if (!(ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration() + .getJwtConfigurationDto().isContinueOnClaimRetrievalFailure())) { + throw new APIKeyMgtException(APIConstants.JWT_GENERATION_ERROR, e); + } else { + log.error("Error occurred while generating JWT. ", e); + } } - - return false; + validationContext.getValidationInfoDTO().setEndUserToken(jwt); + return true; } private String getCachedJWTToken(TokenValidationContext validationContext) throws APIManagementException { diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json index 48376b4c16e8..d757676109cd 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json @@ -32,6 +32,7 @@ "apim.jwt.encode_x5t_without_padding": false, "apim.jwt.enable_tenant_based_signing": false, "apim.jwt.gateway_generator.enable_claim_retrieval": false, + "apim.jwt.continue_on_claim_retrieval_failure": true, "apim.jwt.binding_federated_user_claims": false, "apim.hashing.hashing_algorithm": "SHA-256", "apim.cache.gateway_token.enable": true, diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 index dcfec78bd2f6..cb5b7643ff5b 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 @@ -86,6 +86,8 @@ + {{apim.jwt.continue_on_claim_retrieval_failure}} + {% if apim.jwt.enable_tenant_based_signing is defined %} {{apim.jwt.enable_tenant_based_signing}} {% endif %}