org.joyrest.oauth2.initializer.OAuth2Initializer.java Source code

Java tutorial

Introduction

Here is the source code for org.joyrest.oauth2.initializer.OAuth2Initializer.java

Source

/*
 * Copyright 2015 Petr Bouda
 *
 * Licensed 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 org.joyrest.oauth2.initializer;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.joyrest.context.initializer.BeanFactory;
import org.joyrest.context.initializer.InitContext;
import org.joyrest.context.initializer.Initializer;
import org.joyrest.oauth2.endpoint.AuthorizationEndpoint;
import org.joyrest.oauth2.endpoint.TokenEndpoint;
import org.joyrest.oauth2.handler.OAuthExceptionConfiguration;
import org.joyrest.oauth2.interceptor.AuthenticationInterceptor;
import org.joyrest.oauth2.interceptor.AuthorizationInterceptor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter;
import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.ClassUtils;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Objects.isNull;

public class OAuth2Initializer implements Initializer {

    @Override
    @SuppressWarnings("unchecked")
    public void init(InitContext context, BeanFactory beanFactory) {
        AuthorizationServerConfiguration authServerConfig = beanFactory.get(AuthorizationServerConfiguration.class);
        TokenStore tokenStore = authServerConfig.getTokenStore();
        UserDetailsService userService = authServerConfig.getUserDetailsService();
        ClientDetailsService clientService = authServerConfig.getClientDetailsService();
        DataSource dataSource = authServerConfig.getDataSource();

        PreAuthenticatedAuthenticationProvider preProvider = new PreAuthenticatedAuthenticationProvider();
        preProvider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper(userService));

        DaoAuthenticationProvider clientAuthProvider = new DaoAuthenticationProvider();
        clientAuthProvider.setUserDetailsService(new ClientDetailsUserDetailsService(clientService));

        DaoAuthenticationProvider userAuthProvider = new DaoAuthenticationProvider();
        userAuthProvider.setUserDetailsService(userService);

        ProviderManager clientManager = new ProviderManager(singletonList(clientAuthProvider));
        ProviderManager userManager = new ProviderManager(asList(userAuthProvider, preProvider));

        AuthorizationCodeServices authServices = new InMemoryAuthorizationCodeServices();
        OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientService);

        DefaultTokenServices tokenServices = tokenServices(clientService, userManager, tokenStore, dataSource);
        TokenGranter tokenGranter = compositeTokenGranter(clientService, userManager, tokenServices, requestFactory,
                authServices);

        TokenEndpoint tokenEndpoint = new TokenEndpoint(clientManager, clientService, tokenGranter);

        TokenStoreUserApprovalHandler userApprovalHandler = new TokenStoreUserApprovalHandler();
        userApprovalHandler.setClientDetailsService(clientService);
        userApprovalHandler.setRequestFactory(requestFactory);
        userApprovalHandler.setTokenStore(tokenStore);

        AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint(authServices, clientService,
                tokenGranter, userApprovalHandler, requestFactory);

        context.addControllerConfiguration(tokenEndpoint);
        context.addControllerConfiguration(authorizationEndpoint);
        context.addExceptionConfiguration(new OAuthExceptionConfiguration());
        context.addInterceptor(new AuthenticationInterceptor(clientManager));
        context.addInterceptor(new AuthorizationInterceptor());
    }

    private TokenGranter compositeTokenGranter(final ClientDetailsService clientService,
            final AuthenticationManager manager, final DefaultTokenServices tokenServices,
            final OAuth2RequestFactory requestFactory, final AuthorizationCodeServices authorizationCodeServices) {

        List<TokenGranter> granters = new ArrayList<>();
        granters.add(new ClientCredentialsTokenGranter(tokenServices, clientService, requestFactory));
        granters.add(new ImplicitTokenGranter(tokenServices, clientService, requestFactory));
        granters.add(new ResourceOwnerPasswordTokenGranter(manager, tokenServices, clientService, requestFactory));
        granters.add(new RefreshTokenGranter(tokenServices, clientService, requestFactory));
        granters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientService,
                requestFactory));
        return new CompositeTokenGranter(granters);
    }

    private DefaultTokenServices tokenServices(final ClientDetailsService clientService,
            final AuthenticationManager manager, final TokenStore tokenStore, final DataSource dataSource) {

        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setClientDetailsService(clientService);
        tokenServices.setAuthenticationManager(manager);
        tokenServices.setTokenStore(tokenStore);

        if (isNull(dataSource)) {
            return tokenServices;
        } else {
            return txProxiedTokenServices(tokenServices, dataSource);
        }
    }

    private DefaultTokenServices txProxiedTokenServices(DefaultTokenServices tokenServices, DataSource dataSource) {
        AnnotationTransactionAttributeSource attrSource = new AnnotationTransactionAttributeSource();
        DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        TransactionInterceptor txInterceptor = transactionInterceptor(attrSource, txManager);
        BeanFactoryTransactionAttributeSourceAdvisor txAdvisor = transactionAdvisor(attrSource, txInterceptor);
        ClassLoader classLoader = ClassUtils.getDefaultClassLoader();

        ProxyFactory proxyFactory = new ProxyFactory(tokenServices);
        proxyFactory.addAdvice(txInterceptor);
        proxyFactory.addAdvisor(txAdvisor);
        proxyFactory.setInterfaces(ClassUtils
                .getAllInterfacesForClass(new SingletonTargetSource(tokenServices).getTargetClass(), classLoader));

        return (DefaultTokenServices) proxyFactory.getProxy(classLoader);
    }

    private BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
            AnnotationTransactionAttributeSource source, TransactionInterceptor interceptor) {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(source);
        advisor.setAdvice(interceptor);
        return advisor;
    }

    private TransactionInterceptor transactionInterceptor(AnnotationTransactionAttributeSource source,
            PlatformTransactionManager txManager) {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(source);
        interceptor.setTransactionManager(txManager);
        return interceptor;
    }

}