All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.cellery.security.extensions.km.CelleryExtendedKeyManagerImpl Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
/*
 *  Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

package io.cellery.security.extensions.km;

import io.cellery.security.extensions.util.Utils;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.model.AccessTokenInfo;
import org.wso2.carbon.apimgt.api.model.KeyManagerConfiguration;
import org.wso2.carbon.apimgt.impl.AMDefaultKeyManagerImpl;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.identity.oauth2.dto.OAuth2IntrospectionResponseDTO;
import org.wso2.carbon.identity.oauth2.dto.OAuth2TokenValidationRequestDTO;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;

import java.util.Arrays;

/**
 * Allows signed JWTs issued by trusted external IDPs to be used for API Authentication.
 */
public class CelleryExtendedKeyManagerImpl extends AMDefaultKeyManagerImpl {

    private static final String JWT_TOKEN_TYPE = "jwt";

    public AccessTokenInfo getTokenMetaData(String accessToken) throws APIManagementException {

        if (!Utils.isSignedJWT(accessToken)) {
            // If the access token is not a signed JWT we let AMDefaultKeyManagerImpl class handle it.
            return super.getTokenMetaData(accessToken);
        }

        OAuth2TokenValidationRequestDTO tokenValidationRequest = buildTokenValidationRequest(accessToken);
        OAuth2IntrospectionResponseDTO introspectionResponse = introspectToken(tokenValidationRequest);

        AccessTokenInfo tokenInfo = new AccessTokenInfo();
        if (isTokenInvalid(introspectionResponse)) {
            tokenInfo.setTokenValid(false);
            tokenInfo.setErrorcode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
        } else {
            tokenInfo.setTokenValid(true);
            tokenInfo.setEndUserName(introspectionResponse.getSub());
            tokenInfo.setConsumerKey(introspectionResponse.getClientId());
            // TODO : check on this..
            tokenInfo.setIssuedTime(System.currentTimeMillis());
            tokenInfo.setScope(buildScopes(introspectionResponse));

            // Convert Expiry Time to milliseconds.
            tokenInfo.setValidityPeriod(getExpiryPeriodInMillis(introspectionResponse));

            // If token has am_application_scope, consider the token as an Application token.
            handleScopes(introspectionResponse, tokenInfo);
        }
        return tokenInfo;
    }

    private String[] buildScopes(OAuth2IntrospectionResponseDTO introspectionResponse) {

        return OAuth2Util.buildScopeArray(introspectionResponse.getScope());
    }

    private OAuth2IntrospectionResponseDTO introspectToken(OAuth2TokenValidationRequestDTO requestDTO) {

        OAuth2TokenValidationService tokenValidationService = new OAuth2TokenValidationService();
        return tokenValidationService.buildIntrospectionResponse(requestDTO);
    }

    private boolean isTokenInvalid(OAuth2IntrospectionResponseDTO responseDTO) {

        return !responseDTO.isActive();
    }

    private long getExpiryPeriodInMillis(OAuth2IntrospectionResponseDTO introspectionResponse) {

        return (introspectionResponse.getExp() * 1000L) - System.currentTimeMillis();
    }

    @Override
    public void loadConfiguration(KeyManagerConfiguration configuration) throws APIManagementException {
        // This is a workaround to force APIM to use default values.
        super.loadConfiguration(null);
    }

    private void handleScopes(OAuth2IntrospectionResponseDTO responseDTO, AccessTokenInfo tokenInfo) {

        String[] scopes = OAuth2Util.buildScopeArray(responseDTO.getScope());
        String applicationTokenScope = getConfigurationElementValue(APIConstants.APPLICATION_TOKEN_SCOPE);
        if (scopes != null && applicationTokenScope != null && !applicationTokenScope.isEmpty()) {
            if (Arrays.asList(scopes).contains(applicationTokenScope)) {
                tokenInfo.setApplicationToken(true);
            }
        }
    }

    private OAuth2TokenValidationRequestDTO buildTokenValidationRequest(String accessToken) {

        OAuth2TokenValidationRequestDTO requestDTO = new OAuth2TokenValidationRequestDTO();

        OAuth2TokenValidationRequestDTO.OAuth2AccessToken token = requestDTO.new OAuth2AccessToken();
        token.setIdentifier(accessToken);
        token.setTokenType(JWT_TOKEN_TYPE);

        requestDTO.setAccessToken(token);
        return requestDTO;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy