如何使用 OAuth2 通过 Spring 获取自定义 Principal 对象?

Posted

技术标签:

【中文标题】如何使用 OAuth2 通过 Spring 获取自定义 Principal 对象?【英文标题】:How can I get a custom Principal object with Spring using OAuth2? 【发布时间】:2017-02-03 05:13:15 【问题描述】:

我有一个使用 spring-security-jwt 和 spring-security-oauth2 的 Spring Boot 应用程序。我有一个扩展 UserDetails 的自定义 User 对象和一个从 loadUserByUsername 方法返回此对象的 Custom UserDetailsS​​ervice。

但是当我使用 Authentication 对象的 getPrincipal 方法并尝试转换为我的自定义用户对象时,它失败了,因为主体返回的是一个字符串而不是我的自定义用户对象。

我的实际目标是在每个需要自定义对象细节的方法调用中消除对持久层的访问,这是最重要的。

【问题讨论】:

this answer 可以帮到你 【参考方案1】:

您可以通过将AccessTokenConverter(间接持有您的UserDetailsService)设置为JwtAccessTokenConverter 来做到这一点。见accessTokenConverter()方法。

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter 

    // Other configurations omitted

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
        endpoints.tokenStore(tokenStore())
                .accessTokenConverter(accessTokenConverter())
                .tokenEnhancer(accessTokenConverter())
                .authenticationManager(authenticationManager);
    

    @Bean
    public TokenStore tokenStore() 
        return new JwtTokenStore(accessTokenConverter());
    

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() 
        DefaultUserAuthenticationConverter duac = new DefaultUserAuthenticationConverter();
        duac.setUserDetailsService(userDetailsService);

        DefaultAccessTokenConverter datc = new DefaultAccessTokenConverter();
        datc.setUserTokenConverter(duac);

        JwtAccessTokenConverter jatc = new JwtAccessTokenConverter();
        jatc.setAccessTokenConverter(datc); // IMPORTANT
        jatc.setSigningKey("your-signing-key");
        return jatc;
    

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

【讨论】:

对于碰巧遇到此问题/答案的任何人,这是正确的答案。我试过了,它对我们有用。我们设置 configure(AuthorizationServerEndpointsConfigurer endpoints) 略有不同,但它仍然有效。

以上是关于如何使用 OAuth2 通过 Spring 获取自定义 Principal 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 WebClient 的 spring-security-oauth2 自定义 OAuth2 令牌请求的授权标头?

如何在spring security oauth2授权服务器中通过jwt令牌获取用户信息?

Spring Security 自定义拦截器Filter实现登录认证

带有自定义 TokenGranter 的 Spring Security OAuth2 版本 2.0.+

资源服务器上的 Spring Boot OAuth2 自定义角色

如何使用spring-boot 1.3.0.RC1为oauth2提供自定义安全性配置