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

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

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

spring security能够经过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取到当前用户信息。spring

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

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

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

首先咱们看下,为何oauth2经过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取到的是用户名?this

咱们看下源码code

DefaultUserAuthenticationConverter.javaxml

public Authentication extractAuthentication( Map<String, ?> map )
{
	/* userClaimName是静态常量:username */
	if ( map.containsKey( userClaimName ) )
	{
		Object					principal	= map.get( userClaimName );
		Collection<? extends GrantedAuthority>	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。jwt

咱们看下这个类的调用。

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()获取用户信息了。