spring oauth2如何获取当前登录用户信息

使用spring oauth2框架做授权鉴定。想获取当前用户信息怎么办?

我们知道spring oauth2是基于spring security的实现的。

spring security可以通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取到当前用户信息。

而spring oauth2通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()却只能拿到当前用户的用户名。

然而实际开发过程中,我们较常用到的大部分都是用户的id。

那么怎么通过配置获取当前用户的信息呢?

首先我们看下,为什么oauth2通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取到的是用户名?

我们看下源码

DefaultUserAuthenticationConverter.java

public Authentication extractAuthentication( Map map )
{
    /* userClaimName是静态常量:username */
    if ( map.containsKey( userClaimName ) )
    {
        Object                  principal   = map.get( userClaimName );
        Collection  authorities = getAuthorities( map );
        /* 原因就是这里。如果userDetailsService为空,返回的就是用户名。 */
        if ( userDetailsService != null )
        {
            UserDetails user = userDetailsService.loadUserByUsername( (String) map.get( userClaimName ) );
            authorities = user.getAuthorities();
            principal   = user;
        }
        return(new UsernamePasswordAuthenticationToken( principal, "N/A", authorities ) );
    }
    return(null);
}

那我们就给这个类,设置userDetailsService。

我们看下这个类的调用。

DefaultAccessTokenConverter.java

public class DefaultAccessTokenConverter implements AccessTokenConverter {
    /* 一开始就被初始化好了,所以不能设置userDetailsService */
    private UserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter();


    /* 但是提供了setter接口,所以我们要做的就是覆盖上面的实例。 */
    public void setUserTokenConverter( UserAuthenticationConverter userTokenConverter )
    {
        this.userTokenConverter = userTokenConverter;
    }
}

所以如果是使用DefaultAccessTokenConverter的,代码可以这么写

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    @Override
    public void configure( AuthorizationServerEndpointsConfigurer endpoints ) throws Exception
    {
        endpoints.tokenStore( tokenStore )
        .authenticationManager( manager )
        .allowedTokenEndpointRequestMethods( HttpMethod.GET, HttpMethod.POST )
        .userDetailsService( userService )
        /* .accessTokenConverter(tokenConverter); */


        DefaultAccessTokenConverter converter = new DefaultAccessTokenConverter();
        DefaultUserAuthenticationConverter userAuthenticationConverter
            = new DefaultUserAuthenticationConverter();
        userAuthenticationConverter.setUserDetailsService( userService );
        converter.setUserTokenConverter( userAuthenticationConverter );
        endpoints.accessTokenConverter( converter );
    }
}

如果是用jwtConverter的话,可以这么改。

定义一个accessTokenConverter继承DefaultAccessTokenConverter

public class OauthAccessTokenConverter extends DefaultAccessTokenConverter {
    public OauthAccessTokenConverter( SecurityUserService userService )
    {
        DefaultUserAuthenticationConverter converter = new DefaultUserAuthenticationConverter();
        converter.setUserDetailsService( userService );
        super.setUserTokenConverter( converter );
    }
}

定义一个jwtConverter继承JwtAccessTokenConver

public class OauthJwtAccessTokenConverter extends JwtAccessTokenConverter {
    public OauthJwtAccessTokenConverter( SecurityUserService userService )
    {
        super.setAccessTokenConverter( new OauthAccessTokenConverter( userService ) );
    }
}
spring oauth2如何获取当前登录用户信息

注册bean

@Configuration
public class TokenConfig {
    @Bean
    public TokenStore jwtTokenStore( JwtAccessTokenConverter converter )
    {
        return(new JwtTokenStore( converter ) );
    }


    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter( SecurityUserService userService )
    {
        JwtAccessTokenConverter accessTokenConverter = new OauthJwtAccessTokenConverter( userService );
        accessTokenConverter.setSigningKey( "sign_key" );
        return(accessTokenConverter);
    }
}

Oauth2认证服务

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private AuthenticationManager manager;
    @Autowired
    private SecurityUserService userService;
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private JwtAccessTokenConverter tokenConverter;

    @Override
    public void configure( AuthorizationServerEndpointsConfigurer endpoints ) throws Exception
    {
        endpoints.tokenStore( tokenStore )
        .authenticationManager( manager )
        .allowedTokenEndpointRequestMethods( HttpMethod.GET, HttpMethod.POST )
        .userDetailsService( userService )
        .accessTokenConverter( tokenConverter );
    }
}

最后就可以像spring security一样。

使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取用户信息了。

你可能感兴趣的:(spring oauth2如何获取当前登录用户信息)