use of org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator in project carbon-apimgt by wso2.
the class JWTValidatorTest method testJWTValidatorForNonJTIScenario.
@Test
public void testJWTValidatorForNonJTIScenario() throws ParseException, APISecurityException, APIManagementException, IOException {
Mockito.when(privilegedCarbonContext.getTenantDomain()).thenReturn("carbon.super");
SignedJWT signedJWT = SignedJWT.parse("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" + ".eyJpc3MiOiJodHRwczovL2xvY2FsaG9zdCIsImlhdCI6MTU5OTU0ODE3NCwiZXhwIjoxNjMxMDg0MTc0LC" + "JhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiR2l2ZW5OYW1l" + "IjoiSm9obm55IiwiU3VybmFtZSI6IlJvY2tldCIsIkVtYWlsIjoianJvY2tldEBleGFtcGxlLmNvbSIsIl" + "JvbGUiOlsiTWFuYWdlciIsIlByb2plY3QgQWRtaW5pc3RyYXRvciJdfQ.SSQyg_VTxF5drIogztn2SyEK" + "2wRE07wG6OW3tufD3vo");
ExtendedJWTConfigurationDto jwtConfigurationDto = new ExtendedJWTConfigurationDto();
JWTValidationService jwtValidationService = Mockito.mock(JWTValidationService.class);
APIKeyValidator apiKeyValidator = Mockito.mock(APIKeyValidator.class);
Cache gatewayTokenCache = Mockito.mock(Cache.class);
Cache invalidTokenCache = Mockito.mock(Cache.class);
Cache gatewayKeyCache = Mockito.mock(Cache.class);
Cache gatewayJWTTokenCache = Mockito.mock(Cache.class);
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValid(true);
jwtValidationInfo.setIssuer("https://localhost");
jwtValidationInfo.setRawPayload(signedJWT.getParsedString());
jwtValidationInfo.setJti(UUID.randomUUID().toString());
jwtValidationInfo.setIssuedTime(System.currentTimeMillis());
jwtValidationInfo.setExpiryTime(System.currentTimeMillis() + 5000L);
jwtValidationInfo.setConsumerKey(UUID.randomUUID().toString());
jwtValidationInfo.setUser("user1");
jwtValidationInfo.setKeyManager("Default");
SignedJWTInfo signedJWTInfo = new SignedJWTInfo(signedJWT.getParsedString(), signedJWT, signedJWT.getJWTClaimsSet());
Mockito.when(jwtValidationService.validateJWTToken(signedJWTInfo)).thenReturn(jwtValidationInfo);
JWTValidatorWrapper jwtValidator = new JWTValidatorWrapper("Unlimited", true, apiKeyValidator, false, null, jwtConfigurationDto, jwtValidationService, invalidTokenCache, gatewayTokenCache, gatewayKeyCache, gatewayJWTTokenCache);
MessageContext messageContext = Mockito.mock(Axis2MessageContext.class);
org.apache.axis2.context.MessageContext axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext.class);
Mockito.when(axis2MsgCntxt.getProperty(Constants.Configuration.HTTP_METHOD)).thenReturn("GET");
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);
Mockito.when(messageContext.getProperty(RESTConstants.REST_API_CONTEXT)).thenReturn("/api1");
Mockito.when(messageContext.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION)).thenReturn("1.0");
Mockito.when(messageContext.getProperty(APIConstants.API_ELECTED_RESOURCE)).thenReturn("/pet/findByStatus");
APIManagerConfiguration apiManagerConfiguration = Mockito.mock(APIManagerConfiguration.class);
Mockito.when(apiManagerConfiguration.getFirstProperty(APIConstants.JWT_AUTHENTICATION_SUBSCRIPTION_VALIDATION)).thenReturn("true");
jwtValidator.setApiManagerConfiguration(apiManagerConfiguration);
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
apiKeyValidationInfoDTO.setApiName("api1");
apiKeyValidationInfoDTO.setApiPublisher("admin");
apiKeyValidationInfoDTO.setApiTier("Unlimited");
apiKeyValidationInfoDTO.setAuthorized(true);
Mockito.when(apiKeyValidator.validateScopes(Mockito.any(TokenValidationContext.class), Mockito.anyString())).thenReturn(true);
Mockito.when(apiKeyValidator.validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(apiKeyValidationInfoDTO);
AuthenticationContext authenticate = jwtValidator.authenticate(signedJWTInfo, messageContext);
Mockito.verify(apiKeyValidator).validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
Assert.assertNotNull(authenticate);
Assert.assertEquals(authenticate.getApiName(), "api1");
Assert.assertEquals(authenticate.getApiPublisher(), "admin");
Assert.assertEquals(authenticate.getConsumerKey(), jwtValidationInfo.getConsumerKey());
Mockito.when(gatewayTokenCache.get(signedJWT.getSignature().toString())).thenReturn("carbon.super");
Mockito.when(gatewayKeyCache.get(signedJWT.getSignature().toString())).thenReturn(jwtValidationInfo);
authenticate = jwtValidator.authenticate(signedJWTInfo, messageContext);
Assert.assertNotNull(authenticate);
Assert.assertEquals(authenticate.getApiName(), "api1");
Assert.assertEquals(authenticate.getApiPublisher(), "admin");
Assert.assertEquals(authenticate.getConsumerKey(), jwtValidationInfo.getConsumerKey());
Mockito.verify(jwtValidationService, Mockito.only()).validateJWTToken(signedJWTInfo);
Mockito.verify(gatewayTokenCache, Mockito.atLeast(1)).get(signedJWT.getSignature().toString());
}
use of org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator in project carbon-apimgt by wso2.
the class JWTValidatorTest method testJWTValidatorExpiredInCache.
@Test
public void testJWTValidatorExpiredInCache() throws ParseException, APISecurityException, APIManagementException, IOException {
Mockito.when(privilegedCarbonContext.getTenantDomain()).thenReturn("carbon.super");
SignedJWT signedJWT = SignedJWT.parse("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5UZG1aak00WkRrM05qWTBZemM1T" + "W1abU9EZ3dNVEUzTVdZd05ERTVNV1JsWkRnNE56YzRaQT09In0" + ".eyJhdWQiOiJodHRwOlwvXC9vcmcud3NvMi5hcGltZ3RcL2dhdGV" + "3YXkiLCJzdWIiOiJhZG1pbkBjYXJib24uc3VwZXIiLCJhcHBsaWNhdGlvbiI6eyJvd25lciI6ImFkbWluIiwidGllclF1b3RhVHlwZ" + "SI6InJlcXVlc3RDb3VudCIsInRpZXIiOiJVbmxpbWl0ZWQiLCJuYW1lIjoiRGVmYXVsdEFwcGxpY2F0aW9uIiwiaWQiOjEsInV1aWQ" + "iOm51bGx9LCJzY29wZSI6ImFtX2FwcGxpY2F0aW9uX3Njb3BlIGRlZmF1bHQiLCJpc3MiOiJodHRwczpcL1wvbG9jYWxob3N0Ojk0" + "NDNcL29hdXRoMlwvdG9rZW4iLCJ0aWVySW5mbyI6e30sImtleXR5cGUiOiJQUk9EVUNUSU9OIiwic3Vic2NyaWJlZEFQSXMiOltdL" + "CJjb25zdW1lcktleSI6IlhnTzM5NklIRks3ZUZZeWRycVFlNEhLR3oxa2EiLCJleHAiOjE1OTAzNDIzMTMsImlhdCI6MTU5MDMzO" + "DcxMywianRpIjoiYjg5Mzg3NjgtMjNmZC00ZGVjLThiNzAtYmVkNDVlYjdjMzNkIn0" + ".sBgeoqJn0log5EZflj_G7ADvm6B3KQ9bdfF" + "CEFVQS1U3oY9" + "-cqPwAPyOLLh95pdfjYjakkf1UtjPZjeIupwXnzg0SffIc704RoVlZocAx9Ns2XihjU6Imx2MbXq9ARmQxQkyGVkJ" + "UMTwZ8" + "-SfOnprfrhX2cMQQS8m2Lp7hcsvWFRGKxAKIeyUrbY4ihRIA5vOUrMBWYUx9Di1N7qdKA4S3e8O4KQX2VaZPBzN594c9TG" + "riiH8AuuqnrftfvidSnlRLaFJmko8-QZo8jDepwacaFhtcaPVVJFG4uYP-_" + "-N6sqfxLw3haazPN0_xU0T1zJLPRLC5HPfZMJDMGp" + "EuSe9w");
ExtendedJWTConfigurationDto jwtConfigurationDto = new ExtendedJWTConfigurationDto();
JWTValidationService jwtValidationService = Mockito.mock(JWTValidationService.class);
APIKeyValidator apiKeyValidator = Mockito.mock(APIKeyValidator.class);
Cache gatewayTokenCache = Mockito.mock(Cache.class);
Cache invalidTokenCache = Mockito.mock(Cache.class);
Cache gatewayKeyCache = Mockito.mock(Cache.class);
Cache gatewayJWTTokenCache = Mockito.mock(Cache.class);
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValid(true);
jwtValidationInfo.setIssuer("https://localhost");
jwtValidationInfo.setRawPayload(signedJWT.getParsedString());
jwtValidationInfo.setJti(UUID.randomUUID().toString());
jwtValidationInfo.setIssuedTime(System.currentTimeMillis());
jwtValidationInfo.setExpiryTime(System.currentTimeMillis() + 5L);
jwtValidationInfo.setConsumerKey(UUID.randomUUID().toString());
jwtValidationInfo.setUser("user1");
jwtValidationInfo.setKeyManager("Default");
SignedJWTInfo signedJWTInfo = new SignedJWTInfo(signedJWT.getParsedString(), signedJWT, signedJWT.getJWTClaimsSet());
Mockito.when(jwtValidationService.validateJWTToken(signedJWTInfo)).thenReturn(jwtValidationInfo);
JWTValidatorWrapper jwtValidator = new JWTValidatorWrapper("Unlimited", true, apiKeyValidator, false, null, jwtConfigurationDto, jwtValidationService, invalidTokenCache, gatewayTokenCache, gatewayKeyCache, gatewayJWTTokenCache);
MessageContext messageContext = Mockito.mock(Axis2MessageContext.class);
org.apache.axis2.context.MessageContext axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext.class);
Mockito.when(axis2MsgCntxt.getProperty(Constants.Configuration.HTTP_METHOD)).thenReturn("GET");
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);
Mockito.when(messageContext.getProperty(RESTConstants.REST_API_CONTEXT)).thenReturn("/api1");
Mockito.when(messageContext.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION)).thenReturn("1.0");
Mockito.when(messageContext.getProperty(APIConstants.API_ELECTED_RESOURCE)).thenReturn("/pet/findByStatus");
APIManagerConfiguration apiManagerConfiguration = Mockito.mock(APIManagerConfiguration.class);
Mockito.when(apiManagerConfiguration.getFirstProperty(APIConstants.JWT_AUTHENTICATION_SUBSCRIPTION_VALIDATION)).thenReturn("true");
jwtValidator.setApiManagerConfiguration(apiManagerConfiguration);
OpenAPIParser parser = new OpenAPIParser();
String swagger = IOUtils.toString(this.getClass().getResourceAsStream("/swaggerEntry/openapi.json"));
OpenAPI openAPI = parser.readContents(swagger, null, null).getOpenAPI();
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
apiKeyValidationInfoDTO.setApiName("api1");
apiKeyValidationInfoDTO.setApiPublisher("admin");
apiKeyValidationInfoDTO.setApiTier("Unlimited");
apiKeyValidationInfoDTO.setAuthorized(true);
Mockito.when(apiKeyValidator.validateScopes(Mockito.any(TokenValidationContext.class), Mockito.anyString())).thenReturn(true);
Mockito.when(apiKeyValidator.validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(apiKeyValidationInfoDTO);
AuthenticationContext authenticate = jwtValidator.authenticate(signedJWTInfo, messageContext);
Mockito.verify(apiKeyValidator).validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
Assert.assertNotNull(authenticate);
Assert.assertEquals(authenticate.getApiName(), "api1");
Assert.assertEquals(authenticate.getApiPublisher(), "admin");
Assert.assertEquals(authenticate.getConsumerKey(), jwtValidationInfo.getConsumerKey());
Mockito.when(gatewayTokenCache.get(signedJWT.getJWTClaimsSet().getJWTID())).thenReturn("carbon.super");
jwtValidationInfo.setIssuedTime(System.currentTimeMillis() - 100);
jwtValidationInfo.setExpiryTime(System.currentTimeMillis());
Mockito.when(gatewayKeyCache.get(signedJWT.getJWTClaimsSet().getJWTID())).thenReturn(jwtValidationInfo);
try {
authenticate = jwtValidator.authenticate(signedJWTInfo, messageContext);
} catch (APISecurityException e) {
Assert.assertEquals(e.getErrorCode(), APISecurityConstants.API_AUTH_INVALID_CREDENTIALS);
}
Mockito.verify(jwtValidationService, Mockito.only()).validateJWTToken(signedJWTInfo);
Mockito.verify(gatewayTokenCache, Mockito.atLeast(1)).get(signedJWT.getJWTClaimsSet().getJWTID());
Mockito.verify(invalidTokenCache, Mockito.times(1)).put(signedJWT.getJWTClaimsSet().getJWTID(), "carbon.super");
}
use of org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator in project carbon-apimgt by wso2.
the class JWTValidatorTest method testAuthenticateForGraphQLSubscription.
@Test
public void testAuthenticateForGraphQLSubscription() throws Exception {
Mockito.when(privilegedCarbonContext.getTenantDomain()).thenReturn("carbon.super");
SignedJWT signedJWT = SignedJWT.parse("eyJ4NXQiOiJNell4TW1Ga09HWXdNV0kwWldObU5EY3hOR1l3WW1NNFp" + "UQTNNV0kyTkRBelpHUXpOR00wWkdSbE5qSmtPREZrWkRSaU9URmtNV0ZoTXpVMlpHVmxOZyIsImtpZCI6Ik16WXhNbUZrT0" + "dZd01XSTBaV05tTkRjeE5HWXdZbU00WlRBM01XSTJOREF6WkdRek5HTTBaR1JsTmpKa09ERmtaRFJpT1RGa01XRmhNelUyW" + "kdWbE5nX1JTMjU2IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF1dCI6IkFQUExJQ0FUSU9OIiwiYXVkIjoidT" + "ljaTNDRmRRUDZJNG9DNU84VFcwZklBRXRnYSIsIm5iZiI6MTYzNjkxNTk4OCwiYXpwIjoidTljaTNDRmRRUDZJNG9DNU84VFc" + "wZklBRXRnYSIsInNjb3BlIjoic2NvcGUxIiwiaXNzIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJcL3Rva2Vu" + "IiwiZXhwIjoxNjM2OTE5NTg4LCJpYXQiOjE2MzY5MTU5ODgsImp0aSI6IjJiM2FmYTkxLTBjNDItNGUzNC1iYTliLTc3ZmVkND" + "dkMGNmZCJ9.J8VkCSDUMCUNdJrpbRJy_cj5YazIrdRyNKTJ-9Lv1EabUgwENX1XQcUioSqF686ESI_PvUxYZIwViybVIIGVRuxM" + "Tp9vCMQDWhxXPCuehahul7Ebn0mQtrM7K2fwL0DpyKpI0ER_UYH-PgNvnHS0f3zmJdUBNao2QwuWorXMuwzSw3oPcdHcYmF9" + "Jn024J8Dv3ipHtzEgSc26ULVRaO9bDzJZochzQzqdkxjLMDMBYmKizXOCXEcXJYrEnQpTRHQGOuRN9stXePvO9_gFGVTenun" + "9pBT7Yw7D3Sd-qg-r_AnExOjQu8QwZRjTh_l09YwBYIrMdhSbtXpeAy0GNrc0w");
SignedJWTInfo signedJWTInfo = new SignedJWTInfo(signedJWT.getParsedString(), signedJWT, signedJWT.getJWTClaimsSet());
String apiContext = "/graphql";
String apiVersion = "1.0.0";
ExtendedJWTConfigurationDto jwtConfigurationDto = new ExtendedJWTConfigurationDto();
JWTValidationService jwtValidationService = Mockito.mock(JWTValidationService.class);
APIKeyValidator apiKeyValidator = Mockito.mock(APIKeyValidator.class);
Cache gatewayTokenCache = Mockito.mock(Cache.class);
Cache invalidTokenCache = Mockito.mock(Cache.class);
Cache gatewayKeyCache = Mockito.mock(Cache.class);
Cache gatewayJWTTokenCache = Mockito.mock(Cache.class);
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValid(true);
jwtValidationInfo.setIssuer("https://localhost");
jwtValidationInfo.setRawPayload(signedJWT.getParsedString());
jwtValidationInfo.setJti(UUID.randomUUID().toString());
jwtValidationInfo.setIssuedTime(System.currentTimeMillis());
jwtValidationInfo.setExpiryTime(System.currentTimeMillis() + 5000L);
jwtValidationInfo.setConsumerKey(UUID.randomUUID().toString());
jwtValidationInfo.setUser("user1");
jwtValidationInfo.setKeyManager("Resident Key Manager");
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
apiKeyValidationInfoDTO.setApiName("GraphQLAPI");
apiKeyValidationInfoDTO.setApiPublisher("admin");
apiKeyValidationInfoDTO.setApiTier("Unlimited");
apiKeyValidationInfoDTO.setAuthorized(true);
apiKeyValidationInfoDTO.setGraphQLMaxDepth(3);
apiKeyValidationInfoDTO.setGraphQLMaxComplexity(4);
// testing happy path
Mockito.when(jwtValidationService.validateJWTToken(signedJWTInfo)).thenReturn(jwtValidationInfo);
JWTValidatorWrapper jwtValidator = new JWTValidatorWrapper("Unlimited", true, apiKeyValidator, false, null, jwtConfigurationDto, jwtValidationService, invalidTokenCache, gatewayTokenCache, gatewayKeyCache, gatewayJWTTokenCache);
Mockito.when(apiKeyValidator.validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(apiKeyValidationInfoDTO);
AuthenticationContext authenticate = jwtValidator.authenticateForGraphQLSubscription(signedJWTInfo, apiContext, apiVersion);
Assert.assertNotNull(authenticate);
Assert.assertEquals(authenticate.getApiName(), "GraphQLAPI");
Assert.assertEquals(authenticate.getApiPublisher(), "admin");
Assert.assertEquals(authenticate.getConsumerKey(), jwtValidationInfo.getConsumerKey());
Assert.assertEquals(authenticate.getRequestTokenScopes(), jwtValidationInfo.getScopes());
Assert.assertEquals(authenticate.getGraphQLMaxComplexity(), apiKeyValidationInfoDTO.getGraphQLMaxComplexity());
Assert.assertEquals(authenticate.getGraphQLMaxDepth(), apiKeyValidationInfoDTO.getGraphQLMaxDepth());
// testing token validation failure
jwtValidationInfo.setValid(false);
Mockito.when(jwtValidationService.validateJWTToken(signedJWTInfo)).thenReturn(jwtValidationInfo);
APISecurityException apiSecurityException = null;
try {
jwtValidator.authenticateForGraphQLSubscription(signedJWTInfo, apiContext, apiVersion);
} catch (APISecurityException exception) {
apiSecurityException = exception;
Assert.assertEquals(exception.getErrorCode(), APISecurityConstants.API_AUTH_INVALID_CREDENTIALS);
Assert.assertEquals(exception.getMessage(), "Invalid JWT token");
}
if (apiSecurityException == null) {
Assert.fail();
}
// testing subscription validation failure
jwtValidationInfo.setValid(true);
apiKeyValidationInfoDTO.setAuthorized(false);
apiKeyValidationInfoDTO.setValidationStatus(APIConstants.KeyValidationStatus.API_AUTH_RESOURCE_FORBIDDEN);
try {
jwtValidator.authenticateForGraphQLSubscription(signedJWTInfo, apiContext, apiVersion);
} catch (APISecurityException exception) {
Assert.assertEquals(exception.getErrorCode(), apiKeyValidationInfoDTO.getValidationStatus());
Assert.assertEquals(exception.getMessage(), "User is NOT authorized to access the Resource. API Subscription validation failed.");
}
}
use of org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator in project carbon-apimgt by wso2.
the class JWTValidatorTest method testTamperedTokens.
private void testTamperedTokens(SignedJWT originalToken, SignedJWT tamperedToken) throws ParseException, APIManagementException, APISecurityException {
ExtendedJWTConfigurationDto jwtConfigurationDto = new ExtendedJWTConfigurationDto();
JWTValidationService jwtValidationService = Mockito.mock(JWTValidationService.class);
APIKeyValidator apiKeyValidator = Mockito.mock(APIKeyValidator.class);
Cache gatewayTokenCache = Mockito.mock(Cache.class);
Cache invalidTokenCache = Mockito.mock(Cache.class);
Cache gatewayKeyCache = Mockito.mock(Cache.class);
Cache gatewayJWTTokenCache = Mockito.mock(Cache.class);
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValid(true);
jwtValidationInfo.setIssuer("https://localhost");
jwtValidationInfo.setRawPayload(originalToken.getParsedString());
jwtValidationInfo.setJti(UUID.randomUUID().toString());
jwtValidationInfo.setIssuedTime(System.currentTimeMillis());
jwtValidationInfo.setExpiryTime(System.currentTimeMillis() + 5000000L);
jwtValidationInfo.setConsumerKey(UUID.randomUUID().toString());
jwtValidationInfo.setUser("user1");
jwtValidationInfo.setKeyManager("Default");
SignedJWTInfo signedJWTInfo = new SignedJWTInfo(originalToken.getParsedString(), originalToken, originalToken.getJWTClaimsSet());
SignedJWTInfo signedJWTInfoTampered = new SignedJWTInfo(tamperedToken.getParsedString(), tamperedToken, tamperedToken.getJWTClaimsSet());
Mockito.when(jwtValidationService.validateJWTToken(signedJWTInfo)).thenReturn(jwtValidationInfo);
JWTValidatorWrapper jwtValidator = new JWTValidatorWrapper("Unlimited", true, apiKeyValidator, false, null, jwtConfigurationDto, jwtValidationService, invalidTokenCache, gatewayTokenCache, gatewayKeyCache, gatewayJWTTokenCache);
MessageContext messageContext = Mockito.mock(Axis2MessageContext.class);
org.apache.axis2.context.MessageContext axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext.class);
Mockito.when(axis2MsgCntxt.getProperty(Constants.Configuration.HTTP_METHOD)).thenReturn("GET");
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);
Mockito.when(messageContext.getProperty(RESTConstants.REST_API_CONTEXT)).thenReturn("/api1");
Mockito.when(messageContext.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION)).thenReturn("1.0");
Mockito.when(messageContext.getProperty(APIConstants.API_ELECTED_RESOURCE)).thenReturn("/pet/findByStatus");
APIManagerConfiguration apiManagerConfiguration = Mockito.mock(APIManagerConfiguration.class);
Mockito.when(apiManagerConfiguration.getFirstProperty(APIConstants.JWT_AUTHENTICATION_SUBSCRIPTION_VALIDATION)).thenReturn("true");
jwtValidator.setApiManagerConfiguration(apiManagerConfiguration);
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
apiKeyValidationInfoDTO.setApiName("api1");
apiKeyValidationInfoDTO.setApiPublisher("admin");
apiKeyValidationInfoDTO.setApiTier("Unlimited");
apiKeyValidationInfoDTO.setAuthorized(true);
Mockito.when(apiKeyValidator.validateScopes(Mockito.any(TokenValidationContext.class), Mockito.anyString())).thenReturn(true);
Mockito.when(apiKeyValidator.validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(apiKeyValidationInfoDTO);
AuthenticationContext authenticate = jwtValidator.authenticate(signedJWTInfo, messageContext);
Mockito.verify(apiKeyValidator).validateSubscription(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
Assert.assertNotNull(authenticate);
Assert.assertEquals(authenticate.getApiName(), "api1");
Assert.assertEquals(authenticate.getApiPublisher(), "admin");
Assert.assertEquals(authenticate.getConsumerKey(), jwtValidationInfo.getConsumerKey());
Mockito.when(gatewayTokenCache.get(originalToken.getJWTClaimsSet().getJWTID())).thenReturn("carbon.super");
Mockito.when(gatewayKeyCache.get(originalToken.getJWTClaimsSet().getJWTID())).thenReturn(jwtValidationInfo);
authenticate = jwtValidator.authenticate(signedJWTInfo, messageContext);
Assert.assertNotNull(authenticate);
Assert.assertEquals(authenticate.getApiName(), "api1");
Assert.assertEquals(authenticate.getApiPublisher(), "admin");
Assert.assertEquals(authenticate.getConsumerKey(), jwtValidationInfo.getConsumerKey());
JWTValidationInfo jwtValidationInfoInvalid = new JWTValidationInfo();
jwtValidationInfoInvalid.setValid(false);
jwtValidationInfoInvalid.setValidationCode(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS);
Mockito.when(jwtValidationService.validateJWTToken(signedJWTInfoTampered)).thenReturn(jwtValidationInfoInvalid);
try {
jwtValidator.authenticate(signedJWTInfoTampered, messageContext);
} catch (APISecurityException e) {
Assert.assertEquals(e.getErrorCode(), APISecurityConstants.API_AUTH_INVALID_CREDENTIALS);
}
Mockito.verify(jwtValidationService).validateJWTToken(signedJWTInfo);
Mockito.verify(gatewayTokenCache, Mockito.atLeast(1)).get(originalToken.getJWTClaimsSet().getJWTID());
}
use of org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator 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()));
}
}
Aggregations