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);
}