• 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<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。

    我们看下这个类的调用。

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

      

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

  • 相关阅读:
    如何构建一个优秀的移动网站?谷歌专家教你25招(三)[转]
    如何构建一个优秀的移动网站?谷歌专家教你25招(二)[转]
    如何构建一个优秀的移动网站?谷歌专家教你25招(一)[转]
    如何做到Zero Downtime重启Go服务?
    Go语言AST尝试
    Database Go and JSON
    "创业"半年
    打造完美的go开发环境
    [ReactiveCocoa]最简单的RAC入门操作
    [Node.js]expressjs简单测试连接mysql
  • 原文地址:https://www.cnblogs.com/braska/p/13328330.html
Copyright © 2020-2023  润新知