在 spring security oauth2 中生成令牌时获取用户详细信息

Get the user details while generating the token in spring security oauth2

我正在为我的项目使用 spring boot with spring security oauth2,我想获取生成令牌的用户的用户详细信息。而且我不想单独调用 API 来获取详细信息。

这是我使用的代码。

package authorization;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

import authorization.service.CustomUserDetailsService;

@Configuration
public class OAuth2ServerConfiguration {

    private static final String RESOURCE_ID = "restservice";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends
            ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources
                .resourceId(RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .anyRequest()
                    .fullyAuthenticated();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    public static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {     

        private TokenStore tokenStore = new InMemoryTokenStore();

        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        @Autowired
        private CustomUserDetailsService userDetailsService;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endPoints){
            endPoints
                .tokenStore(this.tokenStore)
                .authenticationManager(this.authenticationManager)
                .userDetailsService(userDetailsService);
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

            clients
                .inMemory()  
                    .withClient("testuser")
                        .authorizedGrantTypes("password","refresh_token")
                        .authorities("USER")
                        .scopes("read","write")
                        .resourceIds(RESOURCE_ID)
                        .secret("testpassword");
        }

        @Bean
        @Primary
        public DefaultTokenServices tokenServices() {
            DefaultTokenServices tokenServices = new DefaultTokenServices();
            tokenServices.setSupportRefreshToken(true);
            tokenServices.setTokenStore(this.tokenStore);
            return tokenServices;
        }       
    }
}

我找到了答案。

package authorization;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

import authorization.service.CustomUserDetailsService;

@Configuration
public class OAuth2ServerConfiguration {

 private static final String RESOURCE_ID = "restservice";
 
 @Configuration
 @EnableResourceServer
 protected static class ResourceServerConfiguration extends
   ResourceServerConfigurerAdapter {

  @Override
  public void configure(ResourceServerSecurityConfigurer resources) {
   resources
    .resourceId(RESOURCE_ID);
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
   http
    .authorizeRequests()
     .anyRequest()
     .fullyAuthenticated();
  }
 }
 
 @Configuration
 @EnableAuthorizationServer
 public static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {  
  
  private TokenStore tokenStore = new InMemoryTokenStore();
  
  @Autowired
  @Qualifier("authenticationManagerBean")
  private AuthenticationManager authenticationManager;
  
  @Autowired
  private CustomUserDetailsService userDetailsService;
  
  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endPoints){
   endPoints
    .tokenStore(this.tokenStore)
    .authenticationManager(this.authenticationManager)
    .userDetailsService(userDetailsService);
  }
  
  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
   
   clients
    .inMemory()  
     .withClient("testuser")
      .authorizedGrantTypes("password","refresh_token")
      .authorities("USER")
      .scopes("read","write")
      .resourceIds(RESOURCE_ID)
      .secret("testpassword");
  }
  
  @Bean
  @Primary
  public DefaultTokenServices tokenServices() {
   DefaultTokenServices tokenServices = new DefaultTokenServices();
   tokenServices.setSupportRefreshToken(true);
   tokenServices.setTokenStore(this.tokenStore);
   tokenServices.setTokenEnhancer(tokenEnhancer());
   return tokenServices;
  }
  // Some @Bean here like tokenStore
  @Bean
  public TokenEnhancer tokenEnhancer() {
   return new CustomTokenEnhancer();
  }

  public class CustomTokenEnhancer implements TokenEnhancer {
   @Override
   public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    User user = (User) authentication.getPrincipal();

    final Map<String, Object> additionalInfo = new HashMap<>();

    additionalInfo.put("User", userDetailsService.viewProfile(user.getUsername()));

    ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

    return accessToken;
   }
  }  
 }
}