Search in sources :

Example 1 with JoseSessionTokenProvider

use of org.apache.cxf.rs.security.oauth2.provider.JoseSessionTokenProvider in project meecrowave by apache.

the class OAuth2Configurer method preCompute.

// TODO: still some missing configuration for jwt etc to add/wire from OAuth2Options
@PostConstruct
private void preCompute() {
    configuration = builder.getExtension(OAuth2Options.class);
    AbstractOAuthDataProvider provider;
    switch(configuration.getProvider().toLowerCase(ENGLISH)) {
        case "jpa":
            {
                if (!configuration.isAuthorizationCodeSupport()) {
                    // else use code impl
                    final JPAOAuthDataProvider jpaProvider = new JPAOAuthDataProvider();
                    jpaProvider.setEntityManagerFactory(JPAAdapter.createEntityManagerFactory(configuration));
                    provider = jpaProvider;
                    break;
                }
            }
        case "jpa-code":
            {
                final JPACodeDataProvider jpaProvider = new JPACodeDataProvider();
                jpaProvider.setEntityManagerFactory(JPAAdapter.createEntityManagerFactory(configuration));
                provider = jpaProvider;
                break;
            }
        case "jcache":
            if (!configuration.isAuthorizationCodeSupport()) {
                // else use code impl
                jCacheConfigurer.doSetup(configuration);
                try {
                    provider = new JCacheOAuthDataProvider(configuration.getJcacheConfigUri(), bus, configuration.isJcacheStoreJwtKeyOnly());
                } catch (final Exception e) {
                    throw new IllegalStateException(e);
                }
                break;
            }
        case "jcache-code":
            jCacheConfigurer.doSetup(configuration);
            try {
                provider = new JCacheCodeDataProvider(configuration, bus);
            } catch (final Exception e) {
                throw new IllegalStateException(e);
            }
            break;
        case // not sure it makes sense since we have jcache but this one is cheap to support
        "ehcache":
            provider = new DefaultEHCacheOAuthDataProvider(configuration.getJcacheConfigUri(), bus);
            break;
        case "encrypted":
            if (!configuration.isAuthorizationCodeSupport()) {
                // else use code impl
                provider = new DefaultEncryptingOAuthDataProvider(new SecretKeySpec(configuration.getEncryptedKey().getBytes(StandardCharsets.UTF_8), configuration.getEncryptedAlgo()));
                break;
            }
        case "encrypted-code":
            provider = new DefaultEncryptingCodeDataProvider(new SecretKeySpec(configuration.getEncryptedKey().getBytes(StandardCharsets.UTF_8), configuration.getEncryptedAlgo()));
            break;
        default:
            throw new IllegalArgumentException("Unsupported oauth2 provider: " + configuration.getProvider());
    }
    final RefreshTokenGrantHandler refreshTokenGrantHandler = new RefreshTokenGrantHandler();
    refreshTokenGrantHandler.setDataProvider(provider);
    refreshTokenGrantHandler.setUseAllClientScopes(configuration.isUseAllClientScopes());
    refreshTokenGrantHandler.setPartialMatchScopeValidation(configuration.isPartialMatchScopeValidation());
    final ResourceOwnerLoginHandler loginHandler = configuration.isJaas() ? new JAASResourceOwnerLoginHandler() : (client, name, password) -> {
        try {
            request.login(name, password);
            try {
                final Principal pcp = request.getUserPrincipal();
                final List<String> roles = GenericPrincipal.class.isInstance(pcp) ? new ArrayList<>(asList(GenericPrincipal.class.cast(pcp).getRoles())) : Collections.<String>emptyList();
                final UserSubject userSubject = new UserSubject(name, roles);
                userSubject.setAuthenticationMethod(PASSWORD);
                return userSubject;
            } finally {
                request.logout();
            }
        } catch (final ServletException e) {
            throw new AuthenticationException(e.getMessage());
        }
    };
    final List<AccessTokenGrantHandler> handlers = new ArrayList<>();
    handlers.add(refreshTokenGrantHandler);
    handlers.add(new ClientCredentialsGrantHandler());
    handlers.add(new ResourceOwnerGrantHandler() {

        {
            setLoginHandler(loginHandler);
        }
    });
    handlers.add(new AuthorizationCodeGrantHandler());
    handlers.add(new JwtBearerGrantHandler());
    provider.setUseJwtFormatForAccessTokens(configuration.isUseJwtFormatForAccessTokens());
    provider.setAccessTokenLifetime(configuration.getAccessTokenLifetime());
    provider.setRefreshTokenLifetime(configuration.getRefreshTokenLifetime());
    provider.setRecycleRefreshTokens(configuration.isRecycleRefreshTokens());
    provider.setSupportPreauthorizedTokens(configuration.isSupportPreauthorizedTokens());
    ofNullable(configuration.getRequiredScopes()).map(s -> asList(s.split(","))).ifPresent(provider::setRequiredScopes);
    ofNullable(configuration.getDefaultScopes()).map(s -> asList(s.split(","))).ifPresent(provider::setDefaultScopes);
    ofNullable(configuration.getInvisibleToClientScopes()).map(s -> asList(s.split(","))).ifPresent(provider::setInvisibleToClientScopes);
    ofNullable(configuration.getJwtAccessTokenClaimMap()).map(s -> new Properties() {

        {
            try {
                load(new StringReader(s));
            } catch (IOException e) {
                throw new IllegalArgumentException("Bad claim map configuration, use properties syntax");
            }
        }
    }).ifPresent(m -> provider.setJwtAccessTokenClaimMap(new HashMap<>(Map.class.cast(m))));
    final OAuthDataProvider dataProvider;
    if (configuration.isRefreshToken()) {
        dataProvider = new RefreshTokenEnabledProvider(provider);
        if (provider.getInvisibleToClientScopes() == null) {
            provider.setInvisibleToClientScopes(new ArrayList<>());
        }
        provider.getInvisibleToClientScopes().add(OAuthConstants.REFRESH_TOKEN_SCOPE);
    } else {
        dataProvider = provider;
    }
    handlers.stream().filter(AbstractGrantHandler.class::isInstance).forEach(h -> {
        final AbstractGrantHandler handler = AbstractGrantHandler.class.cast(h);
        handler.setDataProvider(dataProvider);
        handler.setCanSupportPublicClients(configuration.isCanSupportPublicClients());
        handler.setPartialMatchScopeValidation(configuration.isPartialMatchScopeValidation());
    });
    abstractTokenServiceConsumer = s -> {
        // this is used @RequestScoped so ensure it is not slow for no reason
        s.setCanSupportPublicClients(configuration.isCanSupportPublicClients());
        s.setBlockUnsecureRequests(configuration.isBlockUnsecureRequests());
        s.setWriteCustomErrors(configuration.isWriteCustomErrors());
        s.setWriteOptionalParameters(configuration.isWriteOptionalParameters());
        s.setDataProvider(dataProvider);
    };
    tokenServiceConsumer = s -> {
        // this is used @RequestScoped so ensure it is not slow for no reason
        abstractTokenServiceConsumer.accept(s);
        s.setGrantHandlers(handlers);
    };
    final List<String> noConsentScopes = ofNullable(configuration.getScopesRequiringNoConsent()).map(s -> asList(s.split(","))).orElse(null);
    // we prefix them oauth2.cxf. but otherwise it is the plain cxf config
    final Map<String, String> contextualProperties = ofNullable(builder.getProperties()).map(Properties::stringPropertyNames).orElse(emptySet()).stream().filter(s -> s.startsWith("oauth2.cxf.rs.security.")).collect(toMap(s -> s.substring("oauth2.cxf.".length()), s -> builder.getProperties().getProperty(s)));
    final JoseSessionTokenProvider sessionAuthenticityTokenProvider = new JoseSessionTokenProvider() {

        private int maxDefaultSessionInterval;

        private boolean jweRequired;

        private JweEncryptionProvider jweEncryptor;

        // workaround a NPE of 3.2.0 - https://issues.apache.org/jira/browse/CXF-7504
        @Override
        public String createSessionToken(final MessageContext mc, final MultivaluedMap<String, String> params, final UserSubject subject, final OAuthRedirectionState secData) {
            String stateString = convertStateToString(secData);
            final JwsSignatureProvider jws = getInitializedSigProvider();
            final JweEncryptionProvider jwe = jweEncryptor == null ? JweUtils.loadEncryptionProvider(new JweHeaders(), jweRequired) : jweEncryptor;
            if (jws == null && jwe == null) {
                throw new OAuthServiceException("Session token can not be created");
            }
            if (jws != null) {
                stateString = JwsUtils.sign(jws, stateString, null);
            }
            if (jwe != null) {
                stateString = jwe.encrypt(StringUtils.toBytesUTF8(stateString), null);
            }
            return OAuthUtils.setSessionToken(mc, stateString, maxDefaultSessionInterval);
        }

        public void setJweEncryptor(final JweEncryptionProvider jweEncryptor) {
            super.setJweEncryptor(jweEncryptor);
            this.jweEncryptor = jweEncryptor;
        }

        @Override
        public void setJweRequired(final boolean jweRequired) {
            super.setJweRequired(jweRequired);
            this.jweRequired = jweRequired;
        }

        @Override
        public void setMaxDefaultSessionInterval(final int maxDefaultSessionInterval) {
            super.setMaxDefaultSessionInterval(maxDefaultSessionInterval);
            this.maxDefaultSessionInterval = maxDefaultSessionInterval;
        }
    };
    sessionAuthenticityTokenProvider.setMaxDefaultSessionInterval(configuration.getMaxDefaultSessionInterval());
    // TODO: other configs
    redirectionBasedGrantServiceConsumer = s -> {
        s.setDataProvider(dataProvider);
        s.setBlockUnsecureRequests(configuration.isBlockUnsecureRequests());
        s.setWriteOptionalParameters(configuration.isWriteOptionalParameters());
        s.setUseAllClientScopes(configuration.isUseAllClientScopes());
        s.setPartialMatchScopeValidation(configuration.isPartialMatchScopeValidation());
        s.setUseRegisteredRedirectUriIfPossible(configuration.isUseRegisteredRedirectUriIfPossible());
        s.setMaxDefaultSessionInterval(configuration.getMaxDefaultSessionInterval());
        s.setMatchRedirectUriWithApplicationUri(configuration.isMatchRedirectUriWithApplicationUri());
        s.setScopesRequiringNoConsent(noConsentScopes);
        s.setSessionAuthenticityTokenProvider(sessionAuthenticityTokenProvider);
        // TODO: make it even more contextual, client based?
        final Message currentMessage = PhaseInterceptorChain.getCurrentMessage();
        contextualProperties.forEach(currentMessage::put);
    };
}
Also used : JCacheOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.JCacheOAuthDataProvider) ServletException(javax.servlet.ServletException) StringUtils(org.apache.cxf.common.util.StringUtils) SecretKeySpec(javax.crypto.spec.SecretKeySpec) Collectors.toMap(java.util.stream.Collectors.toMap) AbstractTokenService(org.apache.cxf.rs.security.oauth2.services.AbstractTokenService) ClientCredentialsGrantHandler(org.apache.cxf.rs.security.oauth2.grants.clientcred.ClientCredentialsGrantHandler) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) JCacheCodeDataProvider(org.apache.meecrowave.oauth2.provider.JCacheCodeDataProvider) RefreshTokenEnabledProvider(org.apache.meecrowave.oauth2.data.RefreshTokenEnabledProvider) AuthorizationCodeGrantHandler(org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler) DefaultEncryptingCodeDataProvider(org.apache.cxf.rs.security.oauth2.grants.code.DefaultEncryptingCodeDataProvider) JwtBearerGrantHandler(org.apache.cxf.rs.security.oauth2.grants.jwt.JwtBearerGrantHandler) ResourceOwnerLoginHandler(org.apache.cxf.rs.security.oauth2.grants.owner.ResourceOwnerLoginHandler) ENGLISH(java.util.Locale.ENGLISH) ResourceOwnerGrantHandler(org.apache.cxf.rs.security.oauth2.grants.owner.ResourceOwnerGrantHandler) OAuth2TokenService(org.apache.meecrowave.oauth2.resource.OAuth2TokenService) JPACodeDataProvider(org.apache.cxf.rs.security.oauth2.grants.code.JPACodeDataProvider) JweEncryptionProvider(org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider) StandardCharsets(java.nio.charset.StandardCharsets) JwsSignatureProvider(org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider) JweUtils(org.apache.cxf.rs.security.jose.jwe.JweUtils) OAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider) List(java.util.List) Principal(java.security.Principal) AbstractGrantHandler(org.apache.cxf.rs.security.oauth2.grants.AbstractGrantHandler) PostConstruct(javax.annotation.PostConstruct) ApplicationScoped(javax.enterprise.context.ApplicationScoped) PASSWORD(org.apache.cxf.rs.security.oauth2.common.AuthenticationMethod.PASSWORD) AccessTokenGrantHandler(org.apache.cxf.rs.security.oauth2.provider.AccessTokenGrantHandler) Meecrowave(org.apache.meecrowave.Meecrowave) Bus(org.apache.cxf.Bus) JAASResourceOwnerLoginHandler(org.apache.cxf.rs.security.oauth2.grants.owner.JAASResourceOwnerLoginHandler) OAuthServiceException(org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException) RefreshTokenGrantHandler(org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) AbstractOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthDataProvider) HttpServletRequest(javax.servlet.http.HttpServletRequest) AuthenticationException(org.apache.cxf.interceptor.security.AuthenticationException) MessageContext(org.apache.cxf.jaxrs.ext.MessageContext) DefaultEncryptingOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.DefaultEncryptingOAuthDataProvider) RedirectionBasedGrantService(org.apache.cxf.rs.security.oauth2.services.RedirectionBasedGrantService) OAuthUtils(org.apache.cxf.rs.security.oauth2.utils.OAuthUtils) JoseSessionTokenProvider(org.apache.cxf.rs.security.oauth2.provider.JoseSessionTokenProvider) GenericPrincipal(org.apache.catalina.realm.GenericPrincipal) JweHeaders(org.apache.cxf.rs.security.jose.jwe.JweHeaders) Properties(java.util.Properties) JPAOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProvider) Collections.emptySet(java.util.Collections.emptySet) Message(org.apache.cxf.message.Message) Optional.ofNullable(java.util.Optional.ofNullable) IOException(java.io.IOException) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) Consumer(java.util.function.Consumer) DefaultEHCacheOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.DefaultEHCacheOAuthDataProvider) StringReader(java.io.StringReader) PhaseInterceptorChain(org.apache.cxf.phase.PhaseInterceptorChain) OAuthConstants(org.apache.cxf.rs.security.oauth2.utils.OAuthConstants) UserSubject(org.apache.cxf.rs.security.oauth2.common.UserSubject) JwsUtils(org.apache.cxf.rs.security.jose.jws.JwsUtils) Collections(java.util.Collections) OAuthRedirectionState(org.apache.cxf.rs.security.oauth2.common.OAuthRedirectionState) AbstractGrantHandler(org.apache.cxf.rs.security.oauth2.grants.AbstractGrantHandler) JPAOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProvider) AuthenticationException(org.apache.cxf.interceptor.security.AuthenticationException) HashMap(java.util.HashMap) JweEncryptionProvider(org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider) OAuthServiceException(org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException) ArrayList(java.util.ArrayList) JPACodeDataProvider(org.apache.cxf.rs.security.oauth2.grants.code.JPACodeDataProvider) ResourceOwnerLoginHandler(org.apache.cxf.rs.security.oauth2.grants.owner.ResourceOwnerLoginHandler) JAASResourceOwnerLoginHandler(org.apache.cxf.rs.security.oauth2.grants.owner.JAASResourceOwnerLoginHandler) JoseSessionTokenProvider(org.apache.cxf.rs.security.oauth2.provider.JoseSessionTokenProvider) ServletException(javax.servlet.ServletException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) DefaultEHCacheOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.DefaultEHCacheOAuthDataProvider) JCacheCodeDataProvider(org.apache.meecrowave.oauth2.provider.JCacheCodeDataProvider) JwsSignatureProvider(org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider) OAuthRedirectionState(org.apache.cxf.rs.security.oauth2.common.OAuthRedirectionState) DefaultEncryptingOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.DefaultEncryptingOAuthDataProvider) RefreshTokenGrantHandler(org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler) RefreshTokenEnabledProvider(org.apache.meecrowave.oauth2.data.RefreshTokenEnabledProvider) JCacheOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.JCacheOAuthDataProvider) Collectors.toMap(java.util.stream.Collectors.toMap) Map(java.util.Map) HashMap(java.util.HashMap) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) DefaultEncryptingCodeDataProvider(org.apache.cxf.rs.security.oauth2.grants.code.DefaultEncryptingCodeDataProvider) Message(org.apache.cxf.message.Message) AccessTokenGrantHandler(org.apache.cxf.rs.security.oauth2.provider.AccessTokenGrantHandler) Properties(java.util.Properties) JweHeaders(org.apache.cxf.rs.security.jose.jwe.JweHeaders) UserSubject(org.apache.cxf.rs.security.oauth2.common.UserSubject) ResourceOwnerGrantHandler(org.apache.cxf.rs.security.oauth2.grants.owner.ResourceOwnerGrantHandler) StringReader(java.io.StringReader) MessageContext(org.apache.cxf.jaxrs.ext.MessageContext) AbstractOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthDataProvider) JwtBearerGrantHandler(org.apache.cxf.rs.security.oauth2.grants.jwt.JwtBearerGrantHandler) AuthorizationCodeGrantHandler(org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) OAuthServiceException(org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException) AuthenticationException(org.apache.cxf.interceptor.security.AuthenticationException) IOException(java.io.IOException) ClientCredentialsGrantHandler(org.apache.cxf.rs.security.oauth2.grants.clientcred.ClientCredentialsGrantHandler) JCacheOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.JCacheOAuthDataProvider) OAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider) AbstractOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthDataProvider) DefaultEncryptingOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.DefaultEncryptingOAuthDataProvider) JPAOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProvider) DefaultEHCacheOAuthDataProvider(org.apache.cxf.rs.security.oauth2.provider.DefaultEHCacheOAuthDataProvider) GenericPrincipal(org.apache.catalina.realm.GenericPrincipal) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) JAASResourceOwnerLoginHandler(org.apache.cxf.rs.security.oauth2.grants.owner.JAASResourceOwnerLoginHandler) Principal(java.security.Principal) GenericPrincipal(org.apache.catalina.realm.GenericPrincipal) PostConstruct(javax.annotation.PostConstruct)

Aggregations

IOException (java.io.IOException)1 StringReader (java.io.StringReader)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Principal (java.security.Principal)1 ArrayList (java.util.ArrayList)1 Arrays.asList (java.util.Arrays.asList)1 Collections (java.util.Collections)1 Collections.emptySet (java.util.Collections.emptySet)1 HashMap (java.util.HashMap)1 List (java.util.List)1 ENGLISH (java.util.Locale.ENGLISH)1 Map (java.util.Map)1 Optional.ofNullable (java.util.Optional.ofNullable)1 Properties (java.util.Properties)1 Consumer (java.util.function.Consumer)1 Collectors.toMap (java.util.stream.Collectors.toMap)1 PostConstruct (javax.annotation.PostConstruct)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 ApplicationScoped (javax.enterprise.context.ApplicationScoped)1 Inject (javax.inject.Inject)1