Search in sources :

Example 6 with TokenValidationContext

use of org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext in project carbon-apimgt by wso2.

the class AbstractKeyValidationHandler method validateSubscription.

@Override
public boolean validateSubscription(TokenValidationContext validationContext) throws APIKeyMgtException {
    if (validationContext == null || validationContext.getValidationInfoDTO() == null) {
        return false;
    }
    if (validationContext.isCacheHit()) {
        return true;
    }
    APIKeyValidationInfoDTO dto = validationContext.getValidationInfoDTO();
    if (validationContext.getTokenInfo() != null) {
        if (validationContext.getTokenInfo().isApplicationToken()) {
            dto.setUserType(APIConstants.ACCESS_TOKEN_USER_TYPE_APPLICATION);
        } else {
            dto.setUserType(APIConstants.AUTH_APPLICATION_USER_LEVEL_TOKEN);
        }
        AccessTokenInfo tokenInfo = validationContext.getTokenInfo();
        // Application Token
        if (!hasTokenRequiredAuthLevel(validationContext.getRequiredAuthenticationLevel(), tokenInfo)) {
            dto.setAuthorized(false);
            dto.setValidationStatus(APIConstants.KeyValidationStatus.API_AUTH_INCORRECT_ACCESS_TOKEN_TYPE);
            return false;
        }
    }
    boolean state = false;
    try {
        if (log.isDebugEnabled()) {
            log.debug("Before validating subscriptions : " + dto);
            log.debug("Validation Info : { context : " + validationContext.getContext() + " , " + "version : " + validationContext.getVersion() + " , consumerKey : " + dto.getConsumerKey() + " }");
        }
        state = validateSubscriptionDetails(validationContext.getContext(), validationContext.getVersion(), dto.getConsumerKey(), dto.getKeyManager(), dto);
        if (log.isDebugEnabled()) {
            log.debug("After validating subscriptions : " + dto);
        }
    } catch (APIManagementException e) {
        log.error("Error Occurred while validating subscription.", e);
    }
    return state;
}
Also used : AccessTokenInfo(org.wso2.carbon.apimgt.api.model.AccessTokenInfo) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Example 7 with TokenValidationContext

use of org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext in project carbon-apimgt by wso2.

the class DefaultKeyValidationHandler method validateScopes.

@Override
public boolean validateScopes(TokenValidationContext validationContext) throws APIKeyMgtException {
    if (validationContext.isCacheHit()) {
        return true;
    }
    APIKeyValidationInfoDTO apiKeyValidationInfoDTO = validationContext.getValidationInfoDTO();
    if (apiKeyValidationInfoDTO == null) {
        throw new APIKeyMgtException("Key Validation information not set");
    }
    String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
    String httpVerb = validationContext.getHttpVerb();
    String[] scopes;
    Set<String> scopesSet = apiKeyValidationInfoDTO.getScopes();
    StringBuilder scopeList = new StringBuilder();
    if (scopesSet != null && !scopesSet.isEmpty()) {
        scopes = scopesSet.toArray(new String[scopesSet.size()]);
        if (log.isDebugEnabled() && scopes != null) {
            for (String scope : scopes) {
                scopeList.append(scope);
                scopeList.append(",");
            }
            scopeList.deleteCharAt(scopeList.length() - 1);
            log.debug("Scopes allowed for token : " + validationContext.getAccessToken() + " : " + scopeList.toString());
        }
    }
    String resourceList = validationContext.getMatchingResource();
    List<String> resourceArray;
    if ((APIConstants.GRAPHQL_QUERY.equalsIgnoreCase(validationContext.getHttpVerb())) || (APIConstants.GRAPHQL_MUTATION.equalsIgnoreCase(validationContext.getHttpVerb())) || (APIConstants.GRAPHQL_SUBSCRIPTION.equalsIgnoreCase(validationContext.getHttpVerb()))) {
        resourceArray = new ArrayList<>(Arrays.asList(resourceList.split(",")));
    } else {
        resourceArray = new ArrayList<>(Arrays.asList(resourceList));
    }
    String actualVersion = validationContext.getVersion();
    // Check if the api version has been prefixed with _default_
    if (actualVersion != null && actualVersion.startsWith(APIConstants.DEFAULT_VERSION_PREFIX)) {
        // Remove the prefix from the version.
        actualVersion = actualVersion.split(APIConstants.DEFAULT_VERSION_PREFIX)[1];
    }
    SubscriptionDataStore tenantSubscriptionStore = SubscriptionDataHolder.getInstance().getTenantSubscriptionStore(tenantDomain);
    API api = tenantSubscriptionStore.getApiByContextAndVersion(validationContext.getContext(), actualVersion);
    boolean scopesValidated = false;
    if (api != null) {
        for (String resource : resourceArray) {
            List<URLMapping> resources = api.getResources();
            URLMapping urlMapping = null;
            for (URLMapping mapping : resources) {
                if (Objects.equals(mapping.getHttpMethod(), httpVerb) || "WS".equalsIgnoreCase(api.getApiType())) {
                    if (isResourcePathMatching(resource, mapping)) {
                        urlMapping = mapping;
                        break;
                    }
                }
            }
            if (urlMapping != null) {
                if (urlMapping.getScopes().size() == 0) {
                    scopesValidated = true;
                    continue;
                }
                List<String> mappingScopes = urlMapping.getScopes();
                boolean validate = false;
                for (String scope : mappingScopes) {
                    if (scopesSet.contains(scope)) {
                        scopesValidated = true;
                        validate = true;
                        break;
                    }
                }
                if (!validate && urlMapping.getScopes().size() > 0) {
                    scopesValidated = false;
                    break;
                }
            }
        }
    }
    if (!scopesValidated) {
        apiKeyValidationInfoDTO.setAuthorized(false);
        apiKeyValidationInfoDTO.setValidationStatus(APIConstants.KeyValidationStatus.INVALID_SCOPE);
    }
    return scopesValidated;
}
Also used : SubscriptionDataStore(org.wso2.carbon.apimgt.keymgt.model.SubscriptionDataStore) APIKeyMgtException(org.wso2.carbon.apimgt.keymgt.APIKeyMgtException) URLMapping(org.wso2.carbon.apimgt.api.model.subscription.URLMapping) API(org.wso2.carbon.apimgt.keymgt.model.entity.API) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Example 8 with TokenValidationContext

use of org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext in project carbon-apimgt by wso2.

the class DefaultKeyValidationHandler method getAccessTokenInfo.

private AccessTokenInfo getAccessTokenInfo(TokenValidationContext validationContext) throws APIManagementException {
    Object cachedAccessTokenInfo = CacheProvider.createIntrospectionCache().get(validationContext.getAccessToken());
    if (cachedAccessTokenInfo != null) {
        log.debug("AccessToken available in introspection Cache.");
        return (AccessTokenInfo) cachedAccessTokenInfo;
    }
    String electedKeyManager = null;
    // Obtaining details about the token.
    if (StringUtils.isNotEmpty(validationContext.getTenantDomain())) {
        Map<String, KeyManagerDto> tenantKeyManagers = KeyManagerHolder.getTenantKeyManagers(validationContext.getTenantDomain());
        KeyManager keyManagerInstance = null;
        if (tenantKeyManagers.values().size() == 1) {
            log.debug("KeyManager count is 1");
            Map.Entry<String, KeyManagerDto> entry = tenantKeyManagers.entrySet().iterator().next();
            if (entry != null) {
                KeyManagerDto keyManagerDto = entry.getValue();
                if (keyManagerDto != null && (validationContext.getKeyManagers().contains(APIConstants.KeyManager.API_LEVEL_ALL_KEY_MANAGERS) || validationContext.getKeyManagers().contains(keyManagerDto.getName()))) {
                    if (log.isDebugEnabled()) {
                        log.debug("KeyManager " + keyManagerDto.getName() + " Available in API level KM list " + String.join(",", validationContext.getKeyManagers()));
                    }
                    if (keyManagerDto.getKeyManager() != null && keyManagerDto.getKeyManager().canHandleToken(validationContext.getAccessToken())) {
                        if (log.isDebugEnabled()) {
                            log.debug("KeyManager " + keyManagerDto.getName() + " can handle the token");
                        }
                        keyManagerInstance = keyManagerDto.getKeyManager();
                        electedKeyManager = entry.getKey();
                    }
                }
            }
        } else if (tenantKeyManagers.values().size() > 1) {
            log.debug("KeyManager count is > 1");
            if (validationContext.getKeyManagers().contains(APIConstants.KeyManager.API_LEVEL_ALL_KEY_MANAGERS)) {
                if (log.isDebugEnabled()) {
                    log.debug("API level KeyManagers contains " + APIConstants.KeyManager.API_LEVEL_ALL_KEY_MANAGERS);
                }
                for (Map.Entry<String, KeyManagerDto> keyManagerDtoEntry : tenantKeyManagers.entrySet()) {
                    if (keyManagerDtoEntry.getValue().getKeyManager() != null && keyManagerDtoEntry.getValue().getKeyManager().canHandleToken(validationContext.getAccessToken())) {
                        if (log.isDebugEnabled()) {
                            log.debug("KeyManager " + keyManagerDtoEntry.getValue().getName() + " can handle the token");
                        }
                        keyManagerInstance = keyManagerDtoEntry.getValue().getKeyManager();
                        electedKeyManager = keyManagerDtoEntry.getKey();
                        break;
                    }
                }
            } else {
                for (String selectedKeyManager : validationContext.getKeyManagers()) {
                    KeyManagerDto keyManagerDto = tenantKeyManagers.get(selectedKeyManager);
                    if (keyManagerDto != null && keyManagerDto.getKeyManager() != null && keyManagerDto.getKeyManager().canHandleToken(validationContext.getAccessToken())) {
                        if (log.isDebugEnabled()) {
                            log.debug("KeyManager " + keyManagerDto.getName() + " can handle the token");
                        }
                        keyManagerInstance = keyManagerDto.getKeyManager();
                        electedKeyManager = selectedKeyManager;
                        break;
                    }
                }
            }
        }
        if (keyManagerInstance != null) {
            log.debug("KeyManager instance available to validate token.");
            AccessTokenInfo tokenInfo = keyManagerInstance.getTokenMetaData(validationContext.getAccessToken());
            tokenInfo.setKeyManager(electedKeyManager);
            CacheProvider.getGatewayIntrospectCache().put(validationContext.getAccessToken(), tokenInfo);
            return tokenInfo;
        } else {
            AccessTokenInfo tokenInfo = new AccessTokenInfo();
            tokenInfo.setTokenValid(false);
            tokenInfo.setErrorcode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
            log.debug("KeyManager not available to authorize token.");
            return tokenInfo;
        }
    }
    return null;
}
Also used : AccessTokenInfo(org.wso2.carbon.apimgt.api.model.AccessTokenInfo) KeyManagerDto(org.wso2.carbon.apimgt.impl.dto.KeyManagerDto) KeyManager(org.wso2.carbon.apimgt.api.model.KeyManager) Map(java.util.Map)

Example 9 with TokenValidationContext

use of org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext in project carbon-apimgt by wso2.

the class JWTValidator method validateScopesForGraphQLSubscriptions.

/**
 * Validate scopes for GraphQL subscription API calls using token scopes in authentication context.
 *
 * @param apiContext            API Context
 * @param apiVersion            API Version
 * @param matchingResource      Matching resource
 * @param jwtToken              JWT Token
 * @param authenticationContext AuthenticationContext
 * @throws APISecurityException if an error occurs
 */
public void validateScopesForGraphQLSubscriptions(String apiContext, String apiVersion, String matchingResource, SignedJWTInfo jwtToken, AuthenticationContext authenticationContext) throws APISecurityException {
    String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
    // Generate TokenValidationContext
    TokenValidationContext tokenValidationContext = new TokenValidationContext();
    APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
    Set<String> scopeSet = new HashSet<>();
    scopeSet.addAll(authenticationContext.getRequestTokenScopes());
    apiKeyValidationInfoDTO.setScopes(scopeSet);
    tokenValidationContext.setValidationInfoDTO(apiKeyValidationInfoDTO);
    tokenValidationContext.setAccessToken(jwtToken.getToken());
    tokenValidationContext.setHttpVerb(GraphQLConstants.SubscriptionConstants.HTTP_METHOD_NAME);
    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: " + authenticationContext.getUsername());
        }
    } 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)

Example 10 with TokenValidationContext

use of org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext 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)10 HashMap (java.util.HashMap)5 TokenValidationContext (org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext)5 HashSet (java.util.HashSet)4 Map (java.util.Map)4 Test (org.junit.Test)3 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)3 APIManagementException (org.wso2.carbon.apimgt.api.APIManagementException)3 AccessTokenInfo (org.wso2.carbon.apimgt.api.model.AccessTokenInfo)3 APIKeyMgtException (org.wso2.carbon.apimgt.keymgt.APIKeyMgtException)3 LinkedHashMap (java.util.LinkedHashMap)2 Ignore (org.junit.Ignore)2 KeyManager (org.wso2.carbon.apimgt.api.model.KeyManager)2 URLMapping (org.wso2.carbon.apimgt.api.model.subscription.URLMapping)2 APISecurityException (org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException)2 ClaimsRetriever (org.wso2.carbon.apimgt.impl.token.ClaimsRetriever)2 KeyValidationHandler (org.wso2.carbon.apimgt.keymgt.handlers.KeyValidationHandler)2 API (org.wso2.carbon.apimgt.keymgt.model.entity.API)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1