Spring Security OAuth2 with custom TokenGranter in version 2.0.+

前端 未结 4 868
无人及你
无人及你 2021-01-17 17:50

In previous versions of OAuth2 it was possible to add a custom token granter by adding it to the xml configuration in the element.<

相关标签:
4条回答
  • 2021-01-17 18:12

    According to the documentation, we have :

    Grant Types

    The grant types supported by the AuthorizationEndpoint can be configured via the AuthorizationServerEndpointsConfigurer. By default all grant types are supported except password (see below for details of how to switch it on). The following properties affect grant types:

    authenticationManager: password grants are switched on by injecting an AuthenticationManager. ......

    See documentation. So you can inject the AuthenticationManager like this :

        @Configuration
        @EnableAuthorizationServer
        public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
    
            @Autowired
            private AuthenticationManager authenticationManager;
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                endpoints
                        .authenticationManager(authenticationManager)
    ........
    
    0 讨论(0)
  • 2021-01-17 18:18

    I couldn't find a way to do it because of the dependency on ClientDetailService making it difficult to get the default granters from the getTokenGranter method. I copied over the code from AuthorizationServerEndpointsConfigurer#tokenGranter() and passed in my clientDetailService and other beans directly to the constructors. Note that I add to create a DefaultOAuth2RequestFactory to pass to the granters and to the endpoints:

    public TokenGranter tokenGranter() {
    
                ClientDetailsService clientDetails = clientDetailsService;
                AuthorizationServerTokenServices tokenServices = tokenServices();
                AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
                OAuth2RequestFactory requestFactory = requestFactory();
    
                List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();
    
                tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices,
                        clientDetails, requestFactory));
                tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
                tokenGranters.add(new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory));
                tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
                tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                            clientDetails, requestFactory));
                tokenGranters.add(new CustomTokenGranter(authenticationManager, tokenServices(), clientDetailsService,
                        requestFactory));
    
                return new CompositeTokenGranter(tokenGranters);
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    
            endpoints
                    .tokenServices(tokenServices())
                    .tokenStore(tokenStore())
                    .tokenEnhancer(tokenEnhancer())
                    .authorizationCodeServices(authorizationCodeServices())
                    .userApprovalHandler(userApprovalHandler())
                    .authenticationManager(authenticationManager)
                    .requestFactory(requestFactory())
                    .tokenGranter(tokenGranter());
        }
    

    That being said, I ended up removing that code and simply added another AuthenticationProvider instead because my new grant type was using a subclass of UsernamePasswordAuthenticationToken anyway, which is the Authentication type used by the password grant by default.

    0 讨论(0)
  • 2021-01-17 18:25

    You need to add the default ones too, e.g. using a CompositeTokenGranter:

            List<TokenGranter> tokenGranters = getTokenGranters(); // implementation up to you
            tokenGranter = new CompositeTokenGranter(tokenGranters);
            endpoints.tokenGranter(tokenGranter);
    
    0 讨论(0)
  • 2021-01-17 18:30

    Here is another way. Copied from here.

    In this example, a new custom TokenGranter, named CustomTokenGranter, is added to a CompositeTokenGranter with the default TokenGranters. I like this example because it uses the AuthorizationServerEndpointsConfigurer's public method getTokenGranter() to retrieve the default TokenGranter's.

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.authenticationManager(authenticationManager);
            endpoints.tokenGranter(tokenGranter(endpoints));
        }
    
        private TokenGranter tokenGranter(final AuthorizationServerEndpointsConfigurer endpoints) {
            List<TokenGranter> granters = new ArrayList<TokenGranter>(Arrays.asList(endpoints.getTokenGranter()));
            granters.add(new CustomTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), "custom"));
            return new CompositeTokenGranter(granters);
        }
    
    0 讨论(0)
提交回复
热议问题