ZLT中的设计
授权服务器:负责登录认证、token派发、token刷新、应用接入管理等功能
API网关:添加认证中心的sdk负责所有请求的鉴权,包括登录验证和url级别的权限判断,主要的JWT原理如下:
- 拦截请求获取判断是否带有token参数(parameter和header)
- 通过公钥pubkey.txt解密token
- 判断token中的权限信息是否能访问当前url
- 把用户名和角色信息放到请求的header中,传给后面的微服务
TokenResolver(TokenArgumentResolver类):嵌入在微服务程序中负责获取当前登录人,主要原理如下:
- 判断当前url请求的方法有没有带有@LoginUser注解
- 判断@LoginUser注解的isFull属性是否为true则通过username查询用户对象
- 构建SysUser对象传给目标方法
Spring Security oAuth2 讲解
推荐下面的文档
https://www.funtl.com/zh/spring-security-oauth2/
即要实现下面的几个主要模块:
- AuthorizationConfig 配置
- AbstractTokenGranter 授权
- ClientDetailsService 租户服务
- userDetailsService 用户服务
- TokenStore Token的储存生成服务
@AutoConfigureAfter(AuthorizationServerEndpointsConfigurer.class)
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
/**
* 注入authenticationManager 来支持 password grant type
*/
@Autowired
private AuthenticationManager authenticationManager;
@Resource
private UserDetailsService userDetailsService;
@Autowired
private TokenStore tokenStore;
@Autowired
private WebResponseExceptionTranslator webResponseExceptionTranslator;
@Autowired
private RedisClientDetailsService clientDetailsService;
@Autowired
private RandomValueAuthorizationCodeServices authorizationCodeServices;
@Autowired
private TokenGranter tokenGranter;
代码分析
- ZLT使用oauth-token拦截器, 1) 赋值租户 2) 统一返回token格式
public class OauthTokenAspect {
@Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")
public Object handleControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable {
try {
授权代理授权
@Bean
public TokenGranter tokenGranter() {
if (tokenGranter == null) {
tokenGranter = new TokenGranter() {
private CompositeTokenGranter delegate;
@Override
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
if (delegate == null) {
delegate = new CompositeTokenGranter(getAllTokenGranters());
}
return delegate.grant(grantType, tokenRequest);
}
};
}
return tokenGranter;
}