安全框架
想必一旦涉及到Spring
安全框架,很容易就会想到SpringSecurity
和Shiro
,了解过的都知道,完美的集成一套安全框架是多么麻烦的事情,所以大家都有努力在简化安全框架的集成成本。
我也是在自己做项目中需要集成安全框架才有了这篇文章,上面的两位的集成难度对我这种小菜鸡还是太难了。所以果断寻求别的方案,这不,发现了这个Sa-Token。
Sa-Token 是一个轻量级 Java
权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权
等一系列权限相关问题。
以上介绍复制于官网,在自己体验和使用后,感受就是🥳
Sa-token
使用起来真的非常简单方便,具体使用上,直接看官网就好,这里主要讨论一个问题:
在微服务模式下,auth
(认证中心)的拆解,是归于system
(系统),还是独立的,如果是独立的。。。如果不是独立的。。。
微服务的选择
前面提到了,auth
(认证中心)的拆解,是归于system
(系统),还是独立的。这个问题的产生还是因为微服务下的鉴权稍稍不太一样,一般的方案都是后端对外提供出网关,再由网关对外部请求进行鉴权,然后转发到对应的微服务,微服务之间有可能存在鉴权,也是需要注意的。
auth独立
auth
独立开又可以分为:auth
单独查库直接与db
交互和借助其他微服务完成数据操作两种。
单独查库
单独查库的好处就是不再限制于微服务之间的鉴权影响,可以自己随意调整auth
策略,这也是相对合理些的方案。
借助微服务
auth
与system
本身上就存在不可避免的联系,auth
需要的数据操作存在复用情况,完全可以放在system
中,这倒也挑不出毛病。需要注意的就是微服务之前调用的鉴权问题了。
auth不独立
auth
不独立的就等同于前面的单独查库的效果了,与system
关系更加紧密了,这样来讲其实就只能说是system
包含auth
,有种名存实亡的感觉了。
我的使用
此仅针对于我的使用理解,案例相对简单,仅供参考。
我使用的是auth
独立且借助system
的模式,数据操作都放在了system
中,auth
仅保留一些登录相关的接口,业务逻辑自己实现,借助system
微服务提供的数据能力。
网关统一鉴权
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Configuration public class AuthFilter {
@Bean public SaReactorFilter getSaReactorFilter() { return new SaReactorFilter() .addInclude("/**") .addExclude("/favicon.ico") .setAuth(obj -> { SaRouter.match("/**").notMatch("/auth/login", "/auth/register").check(r -> StpUtil.checkLogin());
}) .setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(GlobalErrorCodeConstants.UNAUTHORIZED.getCode())); } }
|
这里开放了/auth/login
和/auth/register
网关转发鉴权
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Component public class ForwardAuthFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest newRequest = exchange .getRequest() .mutate() .header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()) .build(); ServerWebExchange newExchange = exchange.mutate().request(newRequest).build(); return chain.filter(newExchange); }
@Override public int getOrder() { return -100; } }
|
子服务校验
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @AutoConfiguration public class SecurityConfiguration implements WebMvcConfigurer {
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**"); }
@Bean public SaServletFilter getSaServletFilter() { return new SaServletFilter() .addInclude("/**") .addExclude("/favicon.ico", "/rpc-api/**") .setAuth(obj -> { SaSameUtil.checkCurrentRequestToken(); }) .setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(GlobalErrorCodeConstants.UNAUTHORIZED.getCode())); } }
|
前面的是开启权限注解并拦截所有请求,因为对外的只有网关的请求,网关自会转发到对应的微服务。
后面的是子服务校验规则,这里排除了/rpc-api
的接口,也就是提供出来的微服务接口不受鉴权限制。
当然这样使用可能存在缺陷,也是在摸索中嘛