oauth2 通过SecurityContextHolder获取用户信息

最近在写oauth2项目,权限模块和资源模块是分离的。在这里获取用户信息的时候出了问题,只能获取到username 。在陷入困境的时候使用token-info-uri验证直接解析失败。最后通过debug一步一步强推到了解决办法。

这里资源服务器用的验证路径是user-info-uri

security:
  oauth2:
    resource:
      loadBalanced: true
      user-info-uri: http://service-auth/users/current
#      token-info-uri: http://service-auth/oauth/check_token
    client:
      client-secret: 123456
      access-token-uri: http://service-auth/oauth/token
      grant-type: client_credentials,password
      scope: all
      client-id: client

解决办法

资源服务器重写PrincipalExtractor

import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author king
 */
@Component
public class FixedPrincipalExtractor implements PrincipalExtractor {
    private static final String PRINCIPAL = "principal";
    @Override
    public Object extractPrincipal(Map<String, Object> map) {
        return map.get(PRINCIPAL);
    }
}

原理

定位OAuth2AuthenticationProcessingFilter类

import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter;

oauth2 通过SecurityContextHolder获取用户信息_第1张图片
进入AuthenticationManager类
这里用到的是redis的存储方式,jwt的挨个打断点,我也是一个一个试出来的
oauth2 通过SecurityContextHolder获取用户信息_第2张图片
这里,从权限模块能获取到的就是this.tokenServices.loadAuthentication(token);方法
oauth2 通过SecurityContextHolder获取用户信息_第3张图片
再往下打断点,进入ResourceServerTokenServices类
选择进入UserInfoTokenServices类
oauth2 通过SecurityContextHolder获取用户信息_第4张图片
在这里就找到了我们想要的东西

oauth2 通过SecurityContextHolder获取用户信息_第5张图片
直接进入extractPrincipal方法:
而这里就是我们只获取到用户的username的根本原因
oauth2 通过SecurityContextHolder获取用户信息_第6张图片
将FixedPrincipalExtractor直接替换掉就能获取到用户的各种信息了

最后:个人觉得这个方法太过暴力,虽然目前还没有遇到什么bug,推荐有别的方法用别的方法

你可能感兴趣的:(spring,cloud,oauth2实用方法,oauth2,spring,cloud,security)