Oauth2获取当前登录用户信息

Oauth2获取当前登录用户信息

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

使用spring oauth2框架做授权鉴定。想获取当前用户信息,但是拿到的却是用户名

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

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

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

我们看下源码 DefaultUserAuthenticationConverter.java

public Authentication extractAuthentication(Map<String, ?> map) {
    if (map.containsKey("user_name")) {
        Object principal = map.get("user_name");
        Collection<? extends GrantedAuthority> authorities = this.getAuthorities(map);
      	// 原因就是这里。如果userDetailsService为空,返回的就是用户名。
        if (this.userDetailsService != null) {
            UserDetails user = this.userDetailsService.loadUserByUsername((String)map.get("user_name"));
            authorities = user.getAuthorities();
            principal = user;
        }

        return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
    } else {
        return null;
    }
}

所以我们需要注入userDetailsService

我们看下这个类的调用。

DefaultAccessTokenConverter.java

public class DefaultAccessTokenConverter implements AccessTokenConverter {
   // 一开始就被初始化好了,所以不能设置userDetailsService
    private UserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter();
    private boolean includeGrantType;
    private String scopeAttribute = "scope";
    private String clientIdAttribute = "client_id";

    public DefaultAccessTokenConverter() {
    }
	  // 但是提供了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);
				//new DefaultAccessTokenConverter类 调用setUserTokenConverter覆盖上面的实例
        DefaultAccessTokenConverter converter = new DefaultAccessTokenConverter();
        DefaultUserAuthenticationConverter userAuthenticationConverter
                = new DefaultUserAuthenticationConverter();
        userAuthenticationConverter.setUserDetailsService(userService);
        converter.setUserTokenConverter(userAuthenticationConverter);
        endpoints.accessTokenConverter(converter);
    }
}

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

定义一个accessTokenConverter继承DefaultAccessTokenConverter

/**
 * @author yz
 * spring oauth2获取当前登录用户信息。
 */
public class OauthAccessTokenConverter extends DefaultAccessTokenConverter {
    public OauthAccessTokenConverter(SecurityUserService userService) {
        DefaultUserAuthenticationConverter converter = new DefaultUserAuthenticationConverter();
        converter.setUserDetailsService( userService);
        super.setUserTokenConverter(converter);
    }
}

定义一个jwtConverter继承JwtAccessTokenConver

/**
 * @author yz
 * spring oauth2获取当前登录用户信息。
 */
public class OauthJwtAccessTokenConverter extends JwtAccessTokenConverter {

    public OauthJwtAccessTokenConverter(SecurityUserService userService) {
        super.setAccessTokenConverter(new OauthAccessTokenConverter(userService));
    }
}

注册bean

/**
 * @author yz
 */
@Configuration
public class JwtTokenConfig {

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new JwtTokenEnhancer();
    }


    @Bean
    public TokenStore jwtTokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
        return new JwtTokenStore(jwtAccessTokenConverter);
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(SecurityUserService userService) {
        JwtAccessTokenConverter accessTokenConverter = new OauthJwtAccessTokenConverter(userService);
        // 签名密钥
        accessTokenConverter.setSigningKey(JWT_TOKEN);
        return accessTokenConverter;
    }
}

Oauth2认证服务

/**
 * description 密码模式需要
 *
 * @param endpoints
 * @return void
 * @author yz
 * @date 2021/11/17 9:40 下午
 * @method configure
 */
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    //jwt扩展信息
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    List<TokenEnhancer> enhancers = new ArrayList<>();
    enhancers.add(tokenEnhancer);
    enhancers.add(jwtAccessTokenConverter);
    enhancerChain.setTokenEnhancers(enhancers);


    endpoints.authenticationManager(authenticationManager).
            userDetailsService(userDetailService)
            .exceptionTranslator(exceptionTranslator)
            .tokenStore(jwtTokenStore)
            .accessTokenConverter(jwtAccessTokenConverter)
            .tokenEnhancer(enhancerChain);
}