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如何获取当前登录用户信息_第1张图片

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

你可能感兴趣的:(java,面试,数据结构,java,spring,python,android,设计模式)