Search in sources :

Example 41 with APIKeyValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.

the class InboundWebsocketProcessorUtilTest method testDoThrottleFail.

@Test
public void testDoThrottleFail() throws ParseException {
    InboundMessageContext inboundMessageContext = new InboundMessageContext();
    int msgSize = 100;
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setThrottling("Gold");
    verbInfoDTO.setRequestKey("liftStatusChange");
    String operationId = "1";
    APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
    apiKeyValidationInfoDTO.setApplicationTier(APIConstants.UNLIMITED_TIER);
    apiKeyValidationInfoDTO.setTier(APIConstants.UNLIMITED_TIER);
    apiKeyValidationInfoDTO.setSubscriberTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
    apiKeyValidationInfoDTO.setSubscriber("admin");
    apiKeyValidationInfoDTO.setApiName("GraphQLAPI");
    apiKeyValidationInfoDTO.setApplicationId("12");
    inboundMessageContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
    inboundMessageContext.setApiContext("/graphql");
    inboundMessageContext.setVersion("1.0.0");
    inboundMessageContext.setUserIP("198.162.10.2");
    inboundMessageContext.setInfoDTO(apiKeyValidationInfoDTO);
    String subscriptionLevelThrottleKey = apiKeyValidationInfoDTO.getApplicationId() + ":" + inboundMessageContext.getApiContext() + ":" + inboundMessageContext.getVersion();
    String applicationLevelThrottleKey = apiKeyValidationInfoDTO.getApplicationId() + ":" + apiKeyValidationInfoDTO.getSubscriber() + "@" + apiKeyValidationInfoDTO.getSubscriberTenantDomain();
    Mockito.when(dataPublisher.tryPublish(Mockito.anyObject())).thenReturn(true);
    PowerMockito.when(WebsocketUtil.isThrottled(verbInfoDTO.getRequestKey(), subscriptionLevelThrottleKey, applicationLevelThrottleKey)).thenReturn(true);
    InboundProcessorResponseDTO inboundProcessorResponseDTO = InboundWebsocketProcessorUtil.doThrottleForGraphQL(msgSize, verbInfoDTO, inboundMessageContext, operationId);
    Assert.assertTrue(inboundProcessorResponseDTO.isError());
    Assert.assertEquals(inboundProcessorResponseDTO.getErrorMessage(), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE);
    Assert.assertEquals(inboundProcessorResponseDTO.getErrorCode(), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR);
    Assert.assertFalse(inboundProcessorResponseDTO.isCloseConnection());
    JSONParser jsonParser = new JSONParser();
    JSONObject errorJson = (JSONObject) jsonParser.parse(inboundProcessorResponseDTO.getErrorResponseString());
    org.junit.Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_TYPE), GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_TYPE_ERROR);
    org.junit.Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID), "1");
    JSONObject payload = (JSONObject) errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_PAYLOAD);
    org.junit.Assert.assertEquals(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_MESSAGE), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE);
    org.junit.Assert.assertEquals(String.valueOf(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_CODE)), String.valueOf(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR));
}
Also used : JSONObject(org.json.simple.JSONObject) VerbInfoDTO(org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO) InboundProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO) InboundMessageContext(org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext) JSONParser(org.json.simple.parser.JSONParser) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 42 with APIKeyValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.

the class OAuthOpaqueAuthenticatorImpl method isAccessTokenExpired.

private boolean isAccessTokenExpired(OAuthTokenInfo accessTokenInfo) {
    APIKeyValidationInfoDTO infoDTO = new APIKeyValidationInfoDTO();
    infoDTO.setValidityPeriod(accessTokenInfo.getValidityPeriod());
    infoDTO.setIssuedTime(accessTokenInfo.getIssuedTime());
    return APIUtil.isAccessTokenExpired(infoDTO);
}
Also used : APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Example 43 with APIKeyValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.

the class InboundWebsocketProcessorUtil method isAuthenticated.

/**
 * Authenticate inbound websocket request handshake.
 *
 * @param inboundMessageContext InboundMessageContext
 * @return whether authenticated or not
 * @throws APIManagementException if an internal error occurs
 * @throws APISecurityException   if authentication fails
 */
public static boolean isAuthenticated(InboundMessageContext inboundMessageContext) throws APISecurityException, APIManagementException {
    try {
        PrivilegedCarbonContext.startTenantFlow();
        PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(inboundMessageContext.getTenantDomain(), true);
        APIKeyValidationInfoDTO info;
        String authorizationHeader = inboundMessageContext.getRequestHeaders().get(HttpHeaders.AUTHORIZATION);
        inboundMessageContext.getRequestHeaders().put(HttpHeaders.AUTHORIZATION, authorizationHeader);
        String[] auth = authorizationHeader.split(StringUtils.SPACE);
        List<String> keyManagerList = DataHolder.getInstance().getKeyManagersFromUUID(inboundMessageContext.getElectedAPI().getUuid());
        if (APIConstants.CONSUMER_KEY_SEGMENT.equals(auth[0])) {
            String cacheKey;
            boolean isJwtToken = false;
            String apiKey = auth[1];
            if (WebsocketUtil.isRemoveOAuthHeadersFromOutMessage()) {
                inboundMessageContext.getRequestHeaders().remove(HttpHeaders.AUTHORIZATION);
            }
            // Initial guess of a JWT token using the presence of a DOT.
            if (StringUtils.isNotEmpty(apiKey) && apiKey.contains(APIConstants.DOT)) {
                try {
                    // Check if the header part is decoded
                    if (StringUtils.countMatches(apiKey, 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");
                    }
                    inboundMessageContext.setSignedJWTInfo(getSignedJwtInfo(apiKey));
                    String keyManager = ServiceReferenceHolder.getInstance().getJwtValidationService().getKeyManagerNameIfJwtValidatorExist(inboundMessageContext.getSignedJWTInfo());
                    if (StringUtils.isNotEmpty(keyManager)) {
                        if (log.isDebugEnabled()) {
                            log.debug("KeyManager " + keyManager + "found for authenticate token " + GatewayUtils.getMaskedToken(apiKey));
                        }
                        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));
                            }
                            throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
                        }
                    } else {
                        if (log.isDebugEnabled()) {
                            log.debug("KeyManager not found for accessToken " + GatewayUtils.getMaskedToken(apiKey));
                        }
                    }
                } catch (ParseException e) {
                    log.debug("Not a JWT token. Failed to decode the token header.", e);
                } catch (APIManagementException e) {
                    log.error("Error while checking validation of JWT", e);
                    throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
                }
            }
            // Find the authentication scheme based on the token type
            if (isJwtToken) {
                log.debug("The token was identified as a JWT token");
                if (APIConstants.GRAPHQL_API.equals(inboundMessageContext.getElectedAPI().getApiType())) {
                    return InboundWebsocketProcessorUtil.authenticateGraphQLJWTToken(inboundMessageContext);
                } else {
                    return InboundWebsocketProcessorUtil.authenticateWSJWTToken(inboundMessageContext);
                }
            } else {
                log.debug("The token was identified as an OAuth token");
                // If the key have already been validated
                if (WebsocketUtil.isGatewayTokenCacheEnabled()) {
                    cacheKey = WebsocketUtil.getAccessTokenCacheKey(apiKey, inboundMessageContext.getApiContext(), inboundMessageContext.getMatchingResource());
                    info = WebsocketUtil.validateCache(apiKey, cacheKey);
                    if (info != null) {
                        inboundMessageContext.setKeyType(info.getType());
                        inboundMessageContext.setInfoDTO(info);
                        return info.isAuthorized();
                    }
                }
                info = getApiKeyDataForWSClient(apiKey, inboundMessageContext.getTenantDomain(), inboundMessageContext.getApiContext(), inboundMessageContext.getVersion(), keyManagerList);
                if (info == null || !info.isAuthorized()) {
                    return false;
                }
                if (WebsocketUtil.isGatewayTokenCacheEnabled()) {
                    cacheKey = WebsocketUtil.getAccessTokenCacheKey(apiKey, inboundMessageContext.getApiContext(), inboundMessageContext.getMatchingResource());
                    WebsocketUtil.putCache(info, apiKey, cacheKey);
                }
                inboundMessageContext.setKeyType(info.getType());
                inboundMessageContext.setToken(info.getEndUserToken());
                inboundMessageContext.setInfoDTO(info);
                return true;
            }
        } else {
            return false;
        }
    } finally {
        PrivilegedCarbonContext.endTenantFlow();
    }
}
Also used : APISecurityException(org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) ParseException(java.text.ParseException) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Example 44 with APIKeyValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.

the class InboundWebsocketProcessorUtil method validateAuthenticationContext.

/**
 * Validates AuthenticationContext and set APIKeyValidationInfoDTO to InboundMessageContext.
 *
 * @param authenticationContext Validated AuthenticationContext
 * @param inboundMessageContext InboundMessageContext
 * @return true if authenticated
 */
public static boolean validateAuthenticationContext(AuthenticationContext authenticationContext, InboundMessageContext inboundMessageContext) {
    if (authenticationContext == null || !authenticationContext.isAuthenticated()) {
        return false;
    }
    // The information given by the AuthenticationContext is set to an APIKeyValidationInfoDTO object
    // so to feed information analytics and throttle data publishing
    APIKeyValidationInfoDTO info = new APIKeyValidationInfoDTO();
    info.setAuthorized(authenticationContext.isAuthenticated());
    info.setApplicationTier(authenticationContext.getApplicationTier());
    info.setTier(authenticationContext.getTier());
    info.setSubscriberTenantDomain(authenticationContext.getSubscriberTenantDomain());
    info.setSubscriber(authenticationContext.getSubscriber());
    info.setStopOnQuotaReach(authenticationContext.isStopOnQuotaReach());
    info.setApiName(authenticationContext.getApiName());
    info.setApplicationId(authenticationContext.getApplicationId());
    info.setType(authenticationContext.getKeyType());
    info.setApiPublisher(authenticationContext.getApiPublisher());
    info.setApplicationName(authenticationContext.getApplicationName());
    info.setConsumerKey(authenticationContext.getConsumerKey());
    info.setEndUserName(authenticationContext.getUsername());
    info.setApiTier(authenticationContext.getApiTier());
    info.setGraphQLMaxDepth(authenticationContext.getGraphQLMaxDepth());
    info.setGraphQLMaxComplexity(authenticationContext.getGraphQLMaxComplexity());
    inboundMessageContext.setKeyType(info.getType());
    inboundMessageContext.setInfoDTO(info);
    inboundMessageContext.setAuthContext(authenticationContext);
    inboundMessageContext.setInfoDTO(info);
    return authenticationContext.isAuthenticated();
}
Also used : APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Example 45 with APIKeyValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.

the class JWTValidator method validateScopes.

/**
 * Validate scopes bound to the resource of the API being invoked against the scopes specified
 * in the JWT token payload.
 *
 * @param apiContext        API Context
 * @param apiVersion        API Version
 * @param matchingResource  Accessed API resource
 * @param httpMethod        API resource's HTTP method
 * @param jwtValidationInfo Validated JWT Information
 * @param jwtToken          JWT Token
 * @throws APISecurityException in case of scope validation failure
 */
private void validateScopes(String apiContext, String apiVersion, String matchingResource, String httpMethod, JWTValidationInfo jwtValidationInfo, SignedJWTInfo jwtToken) throws APISecurityException {
    String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
    // Generate TokenValidationContext
    TokenValidationContext tokenValidationContext = new TokenValidationContext();
    APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
    Set<String> scopeSet = new HashSet<>();
    scopeSet.addAll(jwtValidationInfo.getScopes());
    apiKeyValidationInfoDTO.setScopes(scopeSet);
    tokenValidationContext.setValidationInfoDTO(apiKeyValidationInfoDTO);
    tokenValidationContext.setAccessToken(jwtToken.getToken());
    tokenValidationContext.setHttpVerb(httpMethod);
    tokenValidationContext.setMatchingResource(matchingResource);
    tokenValidationContext.setContext(apiContext);
    tokenValidationContext.setVersion(apiVersion);
    boolean valid = this.apiKeyValidator.validateScopes(tokenValidationContext, tenantDomain);
    if (valid) {
        if (log.isDebugEnabled()) {
            log.debug("Scope validation successful for the resource: " + matchingResource + ", user: " + jwtValidationInfo.getUser());
        }
    } else {
        String message = "User is NOT authorized to access the Resource: " + matchingResource + ". Scope validation failed.";
        log.debug(message);
        throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, message);
    }
}
Also used : APISecurityException(org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException) TokenValidationContext(org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO) HashSet(java.util.HashSet)

Aggregations

APIKeyValidationInfoDTO (org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)54 Test (org.junit.Test)29 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)28 Cache (javax.cache.Cache)19 APISecurityException (org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException)14 HashMap (java.util.HashMap)13 JWTValidationInfo (org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo)12 TokenValidationContext (org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext)12 Axis2MessageContext (org.apache.synapse.core.axis2.Axis2MessageContext)11 APIKeyValidator (org.wso2.carbon.apimgt.gateway.handlers.security.APIKeyValidator)11 AuthenticationContext (org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext)11 APIManagerConfiguration (org.wso2.carbon.apimgt.impl.APIManagerConfiguration)11 SignedJWTInfo (org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo)10 AxisConfiguration (org.apache.axis2.engine.AxisConfiguration)9 MessageContext (org.apache.synapse.MessageContext)9 ExtendedJWTConfigurationDto (org.wso2.carbon.apimgt.impl.dto.ExtendedJWTConfigurationDto)9 JWTValidationService (org.wso2.carbon.apimgt.impl.jwt.JWTValidationService)9 SignedJWT (com.nimbusds.jwt.SignedJWT)8 APIManagementException (org.wso2.carbon.apimgt.api.APIManagementException)7 APIKeyDataStore (org.wso2.carbon.apimgt.gateway.handlers.security.keys.APIKeyDataStore)7