最近在写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;
进入AuthenticationManager类
这里用到的是redis的存储方式,jwt的挨个打断点,我也是一个一个试出来的
这里,从权限模块能获取到的就是this.tokenServices.loadAuthentication(token);方法
再往下打断点,进入ResourceServerTokenServices类
选择进入UserInfoTokenServices类
在这里就找到了我们想要的东西
直接进入extractPrincipal方法:
而这里就是我们只获取到用户的username的根本原因
将FixedPrincipalExtractor直接替换掉就能获取到用户的各种信息了
最后:个人觉得这个方法太过暴力,虽然目前还没有遇到什么bug,推荐有别的方法用别的方法