Search in sources :

Example 61 with APIKeyValidationInfoDTO

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

the class DefaultKeyValidationHandler method validateToken.

@Override
public boolean validateToken(TokenValidationContext validationContext) throws APIKeyMgtException {
    // If validationInfoDTO is taken from cache, validity of the cached infoDTO is checked with each request.
    if (validationContext.isCacheHit()) {
        APIKeyValidationInfoDTO infoDTO = validationContext.getValidationInfoDTO();
        // TODO: This should only happen in GW
        boolean tokenExpired = APIUtil.isAccessTokenExpired(infoDTO);
        if (tokenExpired) {
            infoDTO.setAuthorized(false);
            infoDTO.setValidationStatus(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
            log.debug("Token " + validationContext.getAccessToken() + " expired.");
            return false;
        } else {
            return true;
        }
    }
    if (StringUtils.isEmpty(validationContext.getAccessToken())) {
        APIKeyValidationInfoDTO infoDTO = validationContext.getValidationInfoDTO();
        infoDTO.setAuthorized(false);
        infoDTO.setValidationStatus(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
        log.debug("Token Not available");
        return false;
    }
    try {
        AccessTokenInfo tokenInfo = getAccessTokenInfo(validationContext);
        if (tokenInfo == null) {
            return false;
        }
        // Setting TokenInfo in validationContext. Methods down in the chain can use TokenInfo.
        validationContext.setTokenInfo(tokenInfo);
        // TODO: Eliminate use of APIKeyValidationInfoDTO if possible
        APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
        validationContext.setValidationInfoDTO(apiKeyValidationInfoDTO);
        if (!tokenInfo.isTokenValid()) {
            apiKeyValidationInfoDTO.setAuthorized(false);
            if (tokenInfo.getErrorcode() > 0) {
                apiKeyValidationInfoDTO.setValidationStatus(tokenInfo.getErrorcode());
            } else {
                apiKeyValidationInfoDTO.setValidationStatus(APIConstants.KeyValidationStatus.API_AUTH_GENERAL_ERROR);
            }
            return false;
        }
        apiKeyValidationInfoDTO.setKeyManager(tokenInfo.getKeyManager());
        apiKeyValidationInfoDTO.setAuthorized(tokenInfo.isTokenValid());
        apiKeyValidationInfoDTO.setEndUserName(tokenInfo.getEndUserName());
        apiKeyValidationInfoDTO.setConsumerKey(tokenInfo.getConsumerKey());
        apiKeyValidationInfoDTO.setIssuedTime(tokenInfo.getIssuedTime());
        apiKeyValidationInfoDTO.setValidityPeriod(tokenInfo.getValidityPeriod());
        if (tokenInfo.getScopes() != null) {
            Set<String> scopeSet = new HashSet<String>(Arrays.asList(tokenInfo.getScopes()));
            apiKeyValidationInfoDTO.setScopes(scopeSet);
        }
        return tokenInfo.isTokenValid();
    } catch (APIManagementException e) {
        log.error("Error while obtaining Token Metadata from Authorization Server", e);
        throw new APIKeyMgtException("Error while obtaining Token Metadata from Authorization Server");
    }
}
Also used : APIKeyMgtException(org.wso2.carbon.apimgt.keymgt.APIKeyMgtException) AccessTokenInfo(org.wso2.carbon.apimgt.api.model.AccessTokenInfo) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO) HashSet(java.util.HashSet)

Example 62 with APIKeyValidationInfoDTO

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

the class APIKeyValidationService method validateKey.

/**
 * Validates the access tokens issued for a particular user to access an API.
 *
 * @param context     Requested context
 * @param accessToken Provided access token
 * @return APIKeyValidationInfoDTO with authorization info and tier info if authorized. If it is not
 * authorized, tier information will be <pre>null</pre>
 * @throws APIKeyMgtException Error occurred when accessing the underlying database or registry.
 */
public APIKeyValidationInfoDTO validateKey(String context, String version, String accessToken, String requiredAuthenticationLevel, String matchingResource, String httpVerb, String tenantDomain, List keyManagers) throws APIKeyMgtException, APIManagementException {
    TracingSpan validateMainSpan = null;
    TracingSpan getAccessTokenCacheSpan = null;
    TracingSpan fetchingKeyValDTOSpan = null;
    TracingSpan validateTokenSpan = null;
    TracingSpan validateSubscriptionSpan = null;
    TracingSpan validateScopeSpan = null;
    TracingSpan generateJWTSpan = null;
    TracingSpan keyCache = null;
    TracingSpan keyValResponseSpan = null;
    TracingTracer tracer = Util.getGlobalTracer();
    Timer timer = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_MAIN"));
    Timer.Context timerContext = timer.start();
    MessageContext axis2MessageContext = MessageContext.getCurrentMessageContext();
    if (Util.tracingEnabled() && axis2MessageContext != null) {
        Map map = (Map) axis2MessageContext.getProperty(MessageContext.TRANSPORT_HEADERS);
        TracingSpan spanContext = Util.extract(tracer, map);
        validateMainSpan = Util.startSpan(TracingConstants.VALIDATE_MAIN, spanContext, tracer);
    }
    Map headersMap = null;
    String activityID = null;
    try {
        if (axis2MessageContext != null) {
            MessageContext responseMessageContext = axis2MessageContext.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
            if (responseMessageContext != null) {
                if (log.isDebugEnabled()) {
                    List headersList = new ArrayList();
                    Object headers = axis2MessageContext.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
                    if (headers != null && headers instanceof Map) {
                        headersMap = (Map) headers;
                        activityID = (String) headersMap.get("activityID");
                    }
                    if (headersMap != null) {
                        headersList.add(new Header("activityID", (String) headersMap.get("activityID")));
                    }
                    responseMessageContext.setProperty(HTTPConstants.HTTP_HEADERS, headersList);
                }
            }
        }
    } catch (AxisFault axisFault) {
        throw new APIKeyMgtException("Error while building response messageContext: " + axisFault.getLocalizedMessage());
    }
    if (log.isDebugEnabled()) {
        String logMsg = "KeyValidation request from gateway: requestTime= " + new SimpleDateFormat("[yyyy.MM.dd HH:mm:ss,SSS zzz]").format(new Date()) + " , for:" + context + " with accessToken=" + accessToken;
        if (activityID != null) {
            logMsg = logMsg + " , transactionId=" + activityID;
        }
        log.debug(logMsg);
    }
    TokenValidationContext validationContext = new TokenValidationContext();
    validationContext.setAccessToken(accessToken);
    validationContext.setContext(context);
    validationContext.setHttpVerb(httpVerb);
    validationContext.setMatchingResource(matchingResource);
    validationContext.setRequiredAuthenticationLevel(requiredAuthenticationLevel);
    validationContext.setValidationInfoDTO(new APIKeyValidationInfoDTO());
    validationContext.setVersion(version);
    validationContext.setTenantDomain(tenantDomain);
    validationContext.setKeyManagers(keyManagers);
    if (Util.tracingEnabled()) {
        getAccessTokenCacheSpan = Util.startSpan(TracingConstants.GET_ACCESS_TOKEN_CACHE_KEY, validateMainSpan, tracer);
    }
    String cacheKey = APIUtil.getAccessTokenCacheKey(accessToken, context, version, matchingResource, httpVerb, requiredAuthenticationLevel);
    validationContext.setCacheKey(cacheKey);
    if (Util.tracingEnabled()) {
        Util.finishSpan(getAccessTokenCacheSpan);
        fetchingKeyValDTOSpan = Util.startSpan(TracingConstants.FETCHING_API_KEY_VAL_INFO_DTO_FROM_CACHE, validateMainSpan, tracer);
    }
    APIKeyValidationInfoDTO infoDTO = APIKeyMgtUtil.getFromKeyManagerCache(cacheKey);
    if (Util.tracingEnabled()) {
        Util.finishSpan(fetchingKeyValDTOSpan);
    }
    if (infoDTO != null) {
        validationContext.setCacheHit(true);
        log.debug("APIKeyValidationInfoDTO fetched from cache. Setting cache hit to true...");
        validationContext.setValidationInfoDTO(infoDTO);
    }
    log.debug("Before calling Validate Token method...");
    Timer timer2 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_TOKEN"));
    Timer.Context timerContext2 = timer2.start();
    if (Util.tracingEnabled()) {
        validateTokenSpan = Util.startSpan(TracingConstants.VALIDATE_TOKEN, validateMainSpan, tracer);
    }
    KeyValidationHandler keyValidationHandler = ServiceReferenceHolder.getInstance().getKeyValidationHandler(tenantDomain);
    boolean state = keyValidationHandler.validateToken(validationContext);
    timerContext2.stop();
    if (Util.tracingEnabled()) {
        Util.finishSpan(validateTokenSpan);
    }
    log.debug("State after calling validateToken ... " + state);
    if (state) {
        Timer timer3 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_SUBSCRIPTION"));
        Timer.Context timerContext3 = timer3.start();
        if (Util.tracingEnabled()) {
            validateSubscriptionSpan = Util.startSpan(TracingConstants.VALIDATE_SUBSCRIPTION, validateMainSpan, tracer);
        }
        state = keyValidationHandler.validateSubscription(validationContext);
        timerContext3.stop();
        if (Util.tracingEnabled()) {
            Util.finishSpan(validateSubscriptionSpan);
        }
    }
    log.debug("State after calling validateSubscription... " + state);
    if (state) {
        Timer timer4 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_SCOPES"));
        Timer.Context timerContext4 = timer4.start();
        if (Util.tracingEnabled()) {
            validateScopeSpan = Util.startSpan(TracingConstants.VALIDATE_SCOPES, validateMainSpan, tracer);
        }
        state = keyValidationHandler.validateScopes(validationContext);
        timerContext4.stop();
        if (Util.tracingEnabled()) {
            Util.finishSpan(validateScopeSpan);
        }
    }
    log.debug("State after calling validateScopes... " + state);
    if (state && APIKeyMgtDataHolder.isJwtGenerationEnabled() && validationContext.getValidationInfoDTO().getEndUserName() != null && !validationContext.isCacheHit()) {
        Timer timer5 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "GENERATE_JWT"));
        Timer.Context timerContext5 = timer5.start();
        if (Util.tracingEnabled()) {
            generateJWTSpan = Util.startSpan(TracingConstants.GENERATE_JWT, validateMainSpan, tracer);
        }
        keyValidationHandler.generateConsumerToken(validationContext);
        timerContext5.stop();
        if (Util.tracingEnabled()) {
            Util.finishSpan(generateJWTSpan);
        }
    }
    log.debug("State after calling generateConsumerToken... " + state);
    if (!validationContext.isCacheHit()) {
        if (Util.tracingEnabled()) {
            keyCache = Util.startSpan(TracingConstants.WRITE_TO_KEY_MANAGER_CACHE, validateMainSpan, tracer);
        }
        APIKeyMgtUtil.writeToKeyManagerCache(cacheKey, validationContext.getValidationInfoDTO());
        if (Util.tracingEnabled()) {
            Util.finishSpan(keyCache);
        }
    }
    if (Util.tracingEnabled()) {
        keyValResponseSpan = Util.startSpan(TracingConstants.PUBLISHING_KEY_VALIDATION_RESPONSE, validateMainSpan, tracer);
    }
    if (log.isDebugEnabled() && axis2MessageContext != null) {
        logMessageDetails(axis2MessageContext, validationContext.getValidationInfoDTO());
    }
    if (log.isDebugEnabled()) {
        log.debug("APIKeyValidationInfoDTO before returning : " + validationContext.getValidationInfoDTO());
        log.debug("KeyValidation response from keymanager to gateway for access token:" + accessToken + " at " + new SimpleDateFormat("[yyyy.MM.dd HH:mm:ss,SSS zzz]").format(new Date()));
    }
    if (Util.tracingEnabled()) {
        Util.finishSpan(keyValResponseSpan);
    }
    timerContext.stop();
    if (Util.tracingEnabled() && validateMainSpan != null) {
        Util.finishSpan(validateMainSpan);
    }
    return validationContext.getValidationInfoDTO();
}
Also used : AxisFault(org.apache.axis2.AxisFault) TracingTracer(org.wso2.carbon.apimgt.tracing.TracingTracer) ArrayList(java.util.ArrayList) Date(java.util.Date) APIKeyMgtException(org.wso2.carbon.apimgt.keymgt.APIKeyMgtException) Timer(org.wso2.carbon.metrics.manager.Timer) Header(org.apache.commons.httpclient.Header) KeyValidationHandler(org.wso2.carbon.apimgt.keymgt.handlers.KeyValidationHandler) ArrayList(java.util.ArrayList) List(java.util.List) TracingSpan(org.wso2.carbon.apimgt.tracing.TracingSpan) MessageContext(org.apache.axis2.context.MessageContext) HashMap(java.util.HashMap) Map(java.util.Map) SimpleDateFormat(java.text.SimpleDateFormat) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Example 63 with APIKeyValidationInfoDTO

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

the class TokenGenTest method testJWTGeneration.

// TODO: Have to convert to work with new JWT generation and signing
@Test
@Ignore
public void testJWTGeneration() throws Exception {
    JWTGenerator jwtGen = new JWTGenerator() {

        @Override
        public Map<String, String> convertClaimMap(Map<ClaimMapping, String> userAttributes, String username) {
            return new HashMap<>();
        }
    };
    APIKeyValidationInfoDTO dto = new APIKeyValidationInfoDTO();
    dto.setSubscriber("sastry");
    dto.setApplicationName("hubapp");
    dto.setApplicationId("1");
    dto.setApplicationTier("UNLIMITED");
    dto.setEndUserName("denis");
    dto.setSubscriberTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
    dto.setUserType(APIConstants.ACCESS_TOKEN_USER_TYPE_APPLICATION);
    TokenValidationContext validationContext = new TokenValidationContext();
    validationContext.setValidationInfoDTO(dto);
    validationContext.setContext("cricScore");
    validationContext.setVersion("1.9.0");
    String token = jwtGen.generateToken(validationContext);
    System.out.println("Generated Token: " + token);
    String header = token.split("\\.")[0];
    String decodedHeader = new String(Base64Utils.decode(header));
    System.out.println("Header: " + decodedHeader);
    String body = token.split("\\.")[1];
    String decodedBody = new String(Base64Utils.decode(body));
    System.out.println("Body: " + decodedBody);
    // With end user name not included
    token = jwtGen.generateToken(validationContext);
    System.out.println("Generated Token: " + token);
    header = token.split("\\.")[0];
    decodedHeader = new String(Base64Utils.decode(header));
    System.out.println("Header: " + decodedHeader);
    body = token.split("\\.")[1];
    decodedBody = new String(Base64Utils.decode(body));
    System.out.println("Body: " + decodedBody);
    dto.setUserType(APIConstants.SUBSCRIPTION_USER_TYPE);
    token = jwtGen.generateToken(validationContext);
    System.out.println("Generated Token: " + token);
    header = token.split("\\.")[0];
    decodedHeader = new String(Base64Utils.decode(header));
    System.out.println("Header: " + decodedHeader);
    body = token.split("\\.")[1];
    decodedBody = new String(Base64Utils.decode(body));
    System.out.println("Body: " + decodedBody);
    token = jwtGen.generateToken(validationContext);
    System.out.println("Generated Token: " + token);
    header = token.split("\\.")[0];
    decodedHeader = new String(Base64Utils.decode(header));
    System.out.println("Header: " + decodedHeader);
    body = token.split("\\.")[1];
    decodedBody = new String(Base64Utils.decode(body));
    System.out.println("Body: " + decodedBody);
// we can not do assert eaquals because body includes expiration time.
/*String expectedHeader = "{\"typ\":\"JWT\"}";
        String expectedBody = "{\"iss\":\"wso2.org/products/am\", \"exp\":1349270811075, " +
                              "\"http://wso2.org/claims/subscriber\":\"sastry\", " +
                              "\"http://wso2.org/claims/applicationname\":\"hubapp\", " +
                              "\"http://wso2.org/claims/apicontext\":\"cricScore\", " +
                              "\"http://wso2.org/claims/version\":\"1.9.0\", " +
                              "\"http://wso2.org/claims/tier\":\"Bronze\", " +
                              "\"http://wso2.org/claims/enduser\":\"denis\"}";

        Assert.assertEquals(expectedHeader, decodedHeader);
        Assert.assertEquals(expectedBody, decodedBody);*/
// String decodedToken = new String(Base64Utils.decode(token));
// log.info(decodedToken);
// assertNotNull(decodedToken);
}
Also used : TokenValidationContext(org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO) Ignore(org.junit.Ignore) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 64 with APIKeyValidationInfoDTO

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

the class APIKeyMgtUtil method getFromKeyManagerCache.

/**
 * Get the KeyValidationInfo object from cache, for a given cache-Key
 *
 * @param cacheKey Key for the Cache Entry
 * @return APIKeyValidationInfoDTO
 * @throws APIKeyMgtException
 */
public static APIKeyValidationInfoDTO getFromKeyManagerCache(String cacheKey) {
    APIKeyValidationInfoDTO info = null;
    boolean cacheEnabledKeyMgt = APIKeyMgtDataHolder.getKeyCacheEnabledKeyMgt();
    Cache cache = getKeyManagerCache();
    // We only fetch from cache if KeyMgtValidationInfoCache is enabled.
    if (cacheEnabledKeyMgt) {
        info = (APIKeyValidationInfoDTO) cache.get(cacheKey);
        // If key validation information is not null then only we proceed with cached object
        if (info != null) {
            if (log.isDebugEnabled()) {
                log.debug("Found cached access token for : " + cacheKey + ".");
            }
        }
    }
    return info;
}
Also used : APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO) Cache(javax.cache.Cache)

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