【Spring】借Spring MVC实现透明鉴权

1. 前言

1.1. 什么是透明鉴权?

开发业务代码的时候,不用关心请求自己接口的用户是否合法。鉴权的工作交给架构中的公共代码,自己仅专心于业务实现。

@Controller
public class ThreadLocalController {
    
    @Autowired
    BankAccountService service;
    
    @RequestMapping("/bank/account")
    public ModelAndView doSomething(@RequestParam("id") Long id) {
    	// 省略了userService.getUserById() 的鉴权操作,也不用在方法上增加一个userId参数
        service.doSomething();
        return new ModelAndView();
    }
}

1.2. 有什么好处?

践行 “单一职责” 原则。鉴权与授权都应该是安全模块的内容,当单体架构膨胀到一定程度后,考虑重构为微服务时,安全模块可拔插的特点就有优势了。

1.3. 透明鉴权后,还有什么需要考虑的?

  • 细粒度控制依旧在业务层
    EG: 删除客户资源,要取登录人的信息确保是本人删除

  • ThreadLocal 的技术抉择
    EG: ThreadLocal 用来存储上下文中用户实体,避免User参数层层传递,但是在线程池环境下,ThreadLocal很容易出问题。Spring Cloud Hystrix 默认Thread隔离,要修改成Semaphore才能避免 ThreadLocal 污染。

  • 授权与鉴权的兼容
    EG: 用户获得新的权限,旧的token如何处理(强制下线重新登录还是做兼容)

1.4. 本文的重点是什么?

  • 理清Servlet FilterSpring MVC Interceptor 的能力边界
  • 构建一个透明鉴权的模型,可迁移到Spring Cloud GatewaySpring Security的学习中

2. 一个简单的鉴权流程图

在这里插入图片描述

2.1. 基本思想

  • Filter 能有读取header的能力,根据token是否携带、token是否命中缓存(缓存可以是Session/ConcurrentHashMap/Redis) 转发给对应的url,让Spring的DispatcherServlet接管
    • 缺少token => /token/empty => 返回401
    • token失效 => /token/invalid => 返回403
  • 有效的token会正常进入Spring 的 Controller,这样在Controller层就不用校验用户是否合法了

2.2. 不足与思考

后端接口不需要校验请求的合法性,但是需要请求人的信息时怎么办?
—— 在Filter层访问缓存时,提供一个获取user实体的能力

  • 用户登录写入token - user实体
  • 用户带着token访问,用token获取user实体
  • 在Filter层 把user实体放入threadlocal,让 controller后的代码能获取到user实体
  • 用户信息修改,把缓存的token及user实体清除,确保一致性

3. 引入ThreadLocal 的流程图

在这里插入图片描述

3.1. 不足与思考

  • ThreadLocal 很容易造成内存泄漏
    使用Spring mvc 的 Interceptor 进行后置处理,remove掉ThreadLocal

4. 引入Interceptor 的流程图

在这里插入图片描述

5. 后记

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值