Search in sources :

Example 21 with JWTValidationInfo

use of org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo in project carbon-apimgt by wso2.

the class JWTValidatorImpl method validateToken.

@Override
public JWTValidationInfo validateToken(SignedJWTInfo signedJWTInfo) throws APIManagementException {
    JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
    boolean state;
    try {
        state = validateSignature(signedJWTInfo.getSignedJWT());
        if (state) {
            JWTClaimsSet jwtClaimsSet = signedJWTInfo.getJwtClaimsSet();
            state = isValidCertificateBoundAccessToken(signedJWTInfo);
            if (state) {
                state = validateTokenExpiry(jwtClaimsSet);
                if (state) {
                    jwtValidationInfo.setConsumerKey(getConsumerKey(jwtClaimsSet));
                    jwtValidationInfo.setScopes(getScopes(jwtClaimsSet));
                    jwtValidationInfo.setAppToken(getIsAppToken(jwtClaimsSet));
                    JWTClaimsSet transformedJWTClaimSet = transformJWTClaims(jwtClaimsSet);
                    createJWTValidationInfoFromJWT(jwtValidationInfo, transformedJWTClaimSet);
                    jwtValidationInfo.setRawPayload(signedJWTInfo.getToken());
                    return jwtValidationInfo;
                } else {
                    jwtValidationInfo.setValid(false);
                    jwtValidationInfo.setValidationCode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
                    return jwtValidationInfo;
                }
            } else {
                jwtValidationInfo.setValid(false);
                jwtValidationInfo.setValidationCode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
                return jwtValidationInfo;
            }
        } else {
            jwtValidationInfo.setValid(false);
            jwtValidationInfo.setValidationCode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
            return jwtValidationInfo;
        }
    } catch (ParseException | JWTGeneratorException e) {
        throw new APIManagementException("Error while parsing JWT", e);
    }
}
Also used : APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) ParseException(java.text.ParseException) JWTGeneratorException(org.wso2.carbon.apimgt.common.gateway.exception.JWTGeneratorException) JWTValidationInfo(org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo)

Example 22 with JWTValidationInfo

use of org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo in project carbon-apimgt by wso2.

the class JWTValidatorImplTest method testValidateToken.

@Test
@PrepareForTest({ CertificateMgtUtils.class, JWTUtil.class, APIManagerConfiguration.class, ServiceReferenceHolder.class, APIManagerConfigurationService.class, APIUtil.class, X509CertUtils.class })
public void testValidateToken() {
    TokenIssuerDto tokenIssuerDto = new TokenIssuerDto("https://localhost:9444/services");
    Mockito.when(signedJWT.getHeader()).thenReturn(jwsHeader);
    PowerMockito.mockStatic(JWTUtil.class);
    byte[] encodedCertificateUnmatched = "aaaaaaaaaaaaaaaa".getBytes();
    try {
        PowerMockito.when(JWTUtil.verifyTokenSignature(signedJWT, KeyId)).thenReturn(true);
    } catch (APIManagementException e) {
        log.info("Exception while signature verification. " + e);
        Assert.fail();
    }
    // Create a mock APIManagerConfiguration Object for retrieving properties from the deployment.toml
    PowerMockito.mockStatic(ServiceReferenceHolder.class);
    PowerMockito.mockStatic(APIManagerConfiguration.class);
    PowerMockito.mockStatic(APIManagerConfigurationService.class);
    PowerMockito.mockStatic(APIUtil.class);
    PowerMockito.mockStatic(CertificateMgtUtils.class);
    PowerMockito.mockStatic(X509CertUtils.class);
    APIManagerConfiguration apiManagerConfiguration = PowerMockito.mock(APIManagerConfiguration.class);
    ServiceReferenceHolder serviceReferenceHolder = PowerMockito.mock(ServiceReferenceHolder.class);
    APIManagerConfigurationService apiManagerConfigurationService = PowerMockito.mock(APIManagerConfigurationService.class);
    OAuthServerConfiguration oAuthServerConfiguration = Mockito.mock(OAuthServerConfiguration.class);
    PowerMockito.when(ServiceReferenceHolder.getInstance()).thenReturn(serviceReferenceHolder);
    Mockito.when(serviceReferenceHolder.getAPIManagerConfigurationService()).thenReturn(apiManagerConfigurationService);
    Mockito.when(apiManagerConfigurationService.getAPIManagerConfiguration()).thenReturn(apiManagerConfiguration);
    Mockito.when(oAuthServerConfiguration.getTimeStampSkewInSeconds()).thenReturn(300L);
    Mockito.when(serviceReferenceHolder.getOauthServerConfiguration()).thenReturn(oAuthServerConfiguration);
    JWTValidatorImpl jwtValidator = new JWTValidatorImpl();
    JWKSConfigurationDTO jwksConfigurationDTO = new JWKSConfigurationDTO();
    tokenIssuerDto.setJwksConfigurationDTO(jwksConfigurationDTO);
    jwksConfigurationDTO.setEnabled(false);
    jwtValidator.loadTokenIssuerConfiguration(tokenIssuerDto);
    try {
        JWTValidationInfo validatedInfo = jwtValidator.validateToken(signedJWTInfo);
        assertTrue(validatedInfo.isValid(), "JWT certificate bound access token validation failed even when the" + " configuration is not enabled.");
    } catch (APIManagementException e) {
        Assert.fail();
    }
    // test when certificate is found in the trust store but cnf thumbprint is not matching with the certificate
    MessageContext messageContext = Mockito.mock(Axis2MessageContext.class);
    org.apache.axis2.context.MessageContext axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext.class);
    X509Certificate x509Certificate = Mockito.mock(X509Certificate.class);
    java.security.cert.X509Certificate x509CertificateJava = Mockito.mock(java.security.cert.X509Certificate.class);
    PowerMockito.when(CertificateMgtUtils.convert(x509Certificate)).thenReturn(Optional.of(x509CertificateJava));
    X509Certificate[] sslCertObject = new X509Certificate[] { x509Certificate };
    Mockito.when(axis2MsgCntxt.getProperty(NhttpConstants.SSL_CLIENT_AUTH_CERT_X509)).thenReturn(sslCertObject);
    Map<String, String> headers = new HashMap<>();
    Mockito.when(axis2MsgCntxt.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS)).thenReturn(headers);
    Mockito.when(((Axis2MessageContext) messageContext).getAxis2MessageContext()).thenReturn(axis2MsgCntxt);
    X509Certificate x509CertificateUnMatched = Mockito.mock(X509Certificate.class);
    java.security.cert.X509Certificate x509CertificateUnMatchedJava = Mockito.mock(java.security.cert.X509Certificate.class);
    PowerMockito.when(CertificateMgtUtils.convert(x509CertificateUnMatched)).thenReturn(Optional.of(x509CertificateUnMatchedJava));
    PowerMockito.when(X509CertUtils.computeSHA256Thumbprint(x509CertificateJava)).thenReturn(new Base64URL(CERT_HASH));
    PowerMockito.when(X509CertUtils.computeSHA256Thumbprint(x509CertificateUnMatchedJava)).thenReturn(new Base64URL(encodedCertificateUnmatched.toString()));
    signedJWTInfo.setX509ClientCertificate(x509CertificateUnMatched);
    // Mock the properties read from the deployment.toml
    Mockito.when(apiManagerConfiguration.getFirstProperty(APIConstants.ENABLE_CERTIFICATE_BOUND_ACCESS_TOKEN)).thenReturn("true");
    try {
        JWTValidationInfo validatedInfo = jwtValidator.validateToken(signedJWTInfo);
        assertFalse(validatedInfo.isValid(), "JWT certificate bound access token validation successful even if the certificate thumbprint" + " is incorrect.");
    } catch (APIManagementException e) {
        Assert.fail();
    }
    // validate with correct certificate thumbprint
    signedJWTInfo.setX509ClientCertificate(x509Certificate);
    try {
        JWTValidationInfo validatedInfo = jwtValidator.validateToken(signedJWTInfo);
        assertTrue(validatedInfo.isValid(), "JWT certificate bound access token validation failed with the correct certificate thumbprint.");
    } catch (APIManagementException e) {
        Assert.fail();
    }
    // Test when certificate bound access token validation is enabled and cnf thumbprint validation is successful
    // when client certificate is added in the trust store
    signedJWTInfo.setX509ClientCertificate(null);
    headers.put(BASE64_ENCODED_CLIENT_CERTIFICATE_HEADER, BASE64_ENCODED_CERT);
}
Also used : ServiceReferenceHolder(org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder) JWKSConfigurationDTO(org.wso2.carbon.apimgt.common.gateway.dto.JWKSConfigurationDTO) APIManagerConfiguration(org.wso2.carbon.apimgt.impl.APIManagerConfiguration) APIManagerConfigurationService(org.wso2.carbon.apimgt.impl.APIManagerConfigurationService) HashMap(java.util.HashMap) OAuthServerConfiguration(org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration) TokenIssuerDto(org.wso2.carbon.apimgt.common.gateway.dto.TokenIssuerDto) X509Certificate(javax.security.cert.X509Certificate) Base64URL(com.nimbusds.jose.util.Base64URL) JWTValidationInfo(org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) MessageContext(org.apache.synapse.MessageContext) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) CertificateManagerImplTest(org.wso2.carbon.apimgt.impl.certificatemgt.CertificateManagerImplTest) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 23 with JWTValidationInfo

use of org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo in project carbon-apimgt by wso2.

the class OAuthJwtAuthenticatorImpl method authenticate.

/**
 * @param message cxf message to be authenticated
 * @return true if authentication was successful else false
 */
@Override
public boolean authenticate(Message message) throws APIManagementException {
    RESTAPICacheConfiguration cacheConfiguration = APIUtil.getRESTAPICacheConfig();
    isRESTApiTokenCacheEnabled = cacheConfiguration.isTokenCacheEnabled();
    String accessToken = RestApiUtil.extractOAuthAccessTokenFromMessage(message, RestApiConstants.REGEX_BEARER_PATTERN, RestApiConstants.AUTH_HEADER_NAME);
    if (StringUtils.countMatches(accessToken, APIConstants.DOT) != 2) {
        log.error("Invalid JWT token. The expected token format is <header.payload.signature>");
        return false;
    }
    try {
        SignedJWTInfo signedJWTInfo = getSignedJwt(accessToken);
        String jwtTokenIdentifier = getJWTTokenIdentifier(signedJWTInfo);
        String maskedToken = message.get(RestApiConstants.MASKED_TOKEN).toString();
        URL basePath = new URL(message.get(APIConstants.BASE_PATH).toString());
        // Validate token
        log.debug("Starting JWT token validation " + maskedToken);
        JWTValidationInfo jwtValidationInfo = validateJWTToken(signedJWTInfo, jwtTokenIdentifier, accessToken, maskedToken, basePath);
        if (jwtValidationInfo != null) {
            if (jwtValidationInfo.isValid()) {
                if (isRESTApiTokenCacheEnabled) {
                    getRESTAPITokenCache().put(jwtTokenIdentifier, jwtValidationInfo);
                }
                // Validating scopes
                return handleScopeValidation(message, signedJWTInfo, accessToken);
            } else {
                log.error("Invalid JWT token :" + maskedToken);
                return false;
            }
        } else {
            log.error("Invalid JWT token :" + maskedToken);
            return false;
        }
    } catch (ParseException e) {
        log.error("Not a JWT token. Failed to decode the token. Reason: " + e.getMessage());
    } catch (MalformedURLException e) {
        log.error("Malformed URL found in request path.Reason: " + e.getMessage());
    }
    return false;
}
Also used : MalformedURLException(java.net.MalformedURLException) RESTAPICacheConfiguration(org.wso2.carbon.apimgt.impl.RESTAPICacheConfiguration) ParseException(java.text.ParseException) SignedJWTInfo(org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo) URL(java.net.URL) JWTValidationInfo(org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo)

Example 24 with JWTValidationInfo

use of org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo in project carbon-apimgt by wso2.

the class OAuthJwtAuthenticatorImpl method validateJWTToken.

/**
 * Validate the JWT token.
 *
 * @param jti           jwtTokenIdentifier
 * @param signedJWTInfo signed jwt info object
 * @return JWTValidationInfo : token validated info
 */
@MethodStats
private JWTValidationInfo validateJWTToken(SignedJWTInfo signedJWTInfo, String jti, String accessToken, String maskedToken, URL basePath) throws APIManagementException {
    JWTValidationInfo jwtValidationInfo;
    String issuer = signedJWTInfo.getJwtClaimsSet().getIssuer();
    if (StringUtils.isNotEmpty(issuer)) {
        // validate Issuer
        List<String> tokenAudiences = signedJWTInfo.getJwtClaimsSet().getAudience();
        if (tokenIssuers != null && tokenIssuers.containsKey(issuer)) {
            // validate audience
            if (audiencesMap != null && audiencesMap.get(basePath.getPath()) != null && tokenAudiences.stream().anyMatch(audiencesMap.get(basePath.getPath())::contains)) {
                if (isRESTApiTokenCacheEnabled) {
                    JWTValidationInfo tempJWTValidationInfo = (JWTValidationInfo) getRESTAPITokenCache().get(jti);
                    if (tempJWTValidationInfo != null) {
                        Boolean isExpired = checkTokenExpiration(new Date(tempJWTValidationInfo.getExpiryTime()));
                        if (isExpired) {
                            tempJWTValidationInfo.setValid(false);
                            getRESTAPITokenCache().remove(jti);
                            getRESTAPIInvalidTokenCache().put(jti, tempJWTValidationInfo);
                            log.error("JWT token validation failed. Reason: Expired Token. " + maskedToken);
                            return tempJWTValidationInfo;
                        }
                        // check accessToken
                        if (!tempJWTValidationInfo.getRawPayload().equals(accessToken)) {
                            tempJWTValidationInfo.setValid(false);
                            getRESTAPITokenCache().remove(jti);
                            getRESTAPIInvalidTokenCache().put(jti, tempJWTValidationInfo);
                            log.error("JWT token validation failed. Reason: Invalid Token. " + maskedToken);
                            return tempJWTValidationInfo;
                        }
                        return tempJWTValidationInfo;
                    } else if (getRESTAPIInvalidTokenCache().get(jti) != null) {
                        if (log.isDebugEnabled()) {
                            log.debug("Token retrieved from the invalid token cache. Token: " + maskedToken);
                        }
                        return (JWTValidationInfo) getRESTAPIInvalidTokenCache().get(jti);
                    }
                }
                // info not in cache. validate signature and exp
                JWTValidator jwtValidator = APIMConfigUtil.getJWTValidatorMap().get(issuer);
                jwtValidationInfo = jwtValidator.validateToken(signedJWTInfo);
                if (jwtValidationInfo.isValid()) {
                    // valid token
                    if (isRESTApiTokenCacheEnabled) {
                        getRESTAPITokenCache().put(jti, jwtValidationInfo);
                    }
                } else {
                    // put in invalid cache
                    if (isRESTApiTokenCacheEnabled) {
                        getRESTAPIInvalidTokenCache().put(jti, jwtValidationInfo);
                    }
                    // invalid credentials : 900901 error code
                    log.error("JWT token validation failed. Reason: Invalid Credentials. " + "Make sure you have provided the correct security credentials in the token :" + maskedToken);
                }
            } else {
                if (audiencesMap == null) {
                    log.error("JWT token audience validation failed. Reason: No audiences registered " + "in the server");
                } else if (audiencesMap.get(basePath.getPath()) == null) {
                    log.error("JWT token audience validation failed. Reason: No audiences registered " + "in the server for the base path (" + basePath.getPath() + ")");
                } else {
                    log.error("JWT token audience validation failed. Reason: None of the aud present " + "in the JWT (" + tokenAudiences.toString() + ") matches the intended audience (" + audiencesMap.get(basePath.getPath()).toString() + ") for base path ( " + basePath.getPath() + " ).");
                }
                return null;
            }
        } else {
            // invalid issuer. invalid token
            log.error("JWT token issuer validation failed. Reason: Issuer present in the JWT (" + issuer + ") does not match with the token issuer (" + tokenIssuers.keySet().toString() + ")");
            return null;
        }
    } else {
        log.error("Issuer is not found in the token " + maskedToken);
        return null;
    }
    return jwtValidationInfo;
}
Also used : JWTValidator(org.wso2.carbon.apimgt.impl.jwt.JWTValidator) Date(java.util.Date) JWTValidationInfo(org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo) MethodStats(org.wso2.carbon.apimgt.rest.api.util.MethodStats)

Example 25 with JWTValidationInfo

use of org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo in project carbon-apimgt by wso2.

the class JWTValidator method getUserClaimsFromKeyManager.

private Map<String, String> getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) {
    if (jwtConfigurationDto.isEnableUserClaimRetrievalFromUserStore()) {
        String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
        JWTValidationInfo jwtValidationInfo = jwtInfoDto.getJwtValidationInfo();
        if (jwtValidationInfo != null) {
            KeyManager keyManagerInstance = KeyManagerHolder.getKeyManagerInstance(tenantDomain, jwtValidationInfo.getKeyManager());
            if (keyManagerInstance != null) {
                Map<String, Object> properties = new HashMap<>();
                if (jwtValidationInfo.getRawPayload() != null) {
                    properties.put(APIConstants.KeyManager.ACCESS_TOKEN, jwtValidationInfo.getRawPayload());
                }
                if (!StringUtils.isEmpty(jwtConfigurationDto.getConsumerDialectUri())) {
                    properties.put(APIConstants.KeyManager.CLAIM_DIALECT, jwtConfigurationDto.getConsumerDialectUri());
                }
                properties.put(APIConstants.KeyManager.BINDING_FEDERATED_USER_CLAIMS, jwtConfigurationDto.isBindFederatedUserClaims());
                try {
                    return keyManagerInstance.getUserClaims(jwtInfoDto.getEndUser(), properties);
                } catch (APIManagementException e) {
                    log.error("Error while retrieving User claims from Key Manager ", e);
                }
            }
        }
    }
    return new HashMap<>();
}
Also used : APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) HashMap(java.util.HashMap) JSONObject(org.json.JSONObject) KeyManager(org.wso2.carbon.apimgt.api.model.KeyManager) JWTValidationInfo(org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo)

Aggregations

JWTValidationInfo (org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo)23 APIKeyValidationInfoDTO (org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)14 APISecurityException (org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException)12 Axis2MessageContext (org.apache.synapse.core.axis2.Axis2MessageContext)11 AuthenticationContext (org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext)11 SignedJWTInfo (org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo)11 HashMap (java.util.HashMap)10 SignedJWT (com.nimbusds.jwt.SignedJWT)9 Cache (javax.cache.Cache)9 MessageContext (org.apache.synapse.MessageContext)9 Test (org.junit.Test)9 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)9 APIKeyValidator (org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator)9 APIManagerConfiguration (org.wso2.carbon.apimgt.impl.APIManagerConfiguration)9 ExtendedJWTConfigurationDto (org.wso2.carbon.apimgt.impl.dto.ExtendedJWTConfigurationDto)9 JWTValidationService (org.wso2.carbon.apimgt.impl.jwt.JWTValidationService)9 TokenValidationContext (org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext)8 JWTInfoDto (org.wso2.carbon.apimgt.common.gateway.dto.JWTInfoDto)6 APIManagementException (org.wso2.carbon.apimgt.api.APIManagementException)5 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)4