前言

RBAC 是基于角色的访问控制(Role-Based Access Control )。权限管理是在任何一个系统里都无法绕过的问题。没有权限控制管理的系统是非常不安全的。
在Spring框架体系中。有非常多的RBAC框架,如Spring Shiro、Spring Security。
而本文介绍的是使用SpringMVC自带的拦截器来实现RBAC权限控制。功能虽然不够全面,但胜在够轻量,能够实现最基本的权限拦截。

实现的关键点:
1.拦截器的使用
2.正则表达式的使用,反向生成权限URL的正则表达式。
3.建立正确的RBAC权限模型

权限数据模型

本文教程使用通用的RBAC权限模型:
用户、角色、权限、用户-角色、角色-权限。如下图所示:

关于RBAC权限模型的更多资料,推荐几个链接:
权限系统与RBAC模型概述[绝对经典]
http://csrc.nist.gov/groups/SNS/rbac/index.html
https://csrc.nist.gov/projects/role-based-access-control

拦截器的实现

这里记录几个要点:

1.拦截器继承自:HandlerInterceptorAdapter
2.拦截器需要加上@Component注解,为了被Ioc容器扫描到
3.拦截器要对不鉴权的URL进行放行
4.给出的代码并非完整代码,只记录了大概的思路。

方法伪代码:

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import lombok.extern.slf4j.Slf4j;/**
* @author ljx
*/
@Slf4j
@Component
public class ValidInterceptor extends HandlerInterceptorAdapter {//公开的URL前缀  private static final String[] PUBLIC_URL_PREFIXES = new String[]{"/upload","/error","/web",};// 公开的URL前缀中要过滤的接口,即公开前缀中需要鉴权的URLprivate static final String[] PUBLIC_URLS_EXCLUDES = new String[]{};private static final String HEADER_AUTHORIZATION = "Authorization";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 对 Options 方法放行if (HttpMethod.OPTIONS.matches(request.getMethod())) {return true;}String method = request.getMethod();String uri = request.getRequestURI();if (StringKit.isNotBlank(uri)) {// uri的一些处理uri = uri.replace("/tomcat", "");}// 不拦截公开的URLif (isPublicUrl(uri)) {return true;}// 从请求中获取访问者信息,通常为用户信息// 可以获取Session或者token来识别信息,如果没有用户信息则可以判定为无权限,返回false// 用户信息通常保存到一个全局的地方。可以是全局缓存(Redis或者内存缓存中)或者数据库中// 代码略// RBAC校验// 由获取到的用户信息,去查询用户拥有的角色,再根据角色去获取对应的权限信息,// 然后对URL和权限列表进行匹配。// 这里每一次都会去数据库查询权限数据,好处是可以动态改变权限,不好的地方是会频繁查库。// 优化方法:// 1.拦截器第一次对某进行拦截时,将该用户的权限信息放到缓存,后面可以从缓存中直接取数据。(无法动态改变权限信息)// 2.没想到,读者自行补充(滑稽脸)Set<String> userRoles; // 用户的角色IDSet<String> roleItems;  // Set保证权限ID唯一List<PermissionEntity> permissions; // 由权限ID集合获取到所有的权限具体信息(不包含菜单类型的URL)// Permission是权限具体信息。必须包含权限的URL,对应的Http方法。// hasPermission方法是对Restful URL进行鉴权的关键方法if (!hasPermission(uri, method, permissions)) {throw new RuntimeException("access.denied");}return super.preHandle(request, response, handler);}private boolean hasPermission(String url, String method, List<PermissionEntity> permissions) {if (ArrayKit.isNullOrEmpty(permissions)) {return false;}for (PermissionEntity permission : permissions) {// getItem() 返回的是权限URLif (StringKit.isBlank(permission.getItem())) {  continue;}// 将Restful风格的url占位符部分改成正则表达式,去匹配url。// 例如/users/{uid}/role的正则表达式为:/users/[^/]*/role// url和method都匹配成功视为有权限String matchRegex = permission.getItem().replaceAll("\\{[^/]*\\}", "[^/]*");if (url.matches(matchRegex)) {// URL的请求方式为*则视为支持所有请求方式if ("*".equals(permission.getMethod()) ||method.toUpperCase(Locale.ROOT).equals(StringKit.toUpperCaseWithSafe(permission.getMethod()))) {return true;}}}return false;}/*** 是否公开的URL** @param url 链接地址* @return 是否公开*/private boolean isPublicUrl(String url) {for (String publicUrl : PUBLIC_URL_PREFIXES) {if (url.startsWith(publicUrl)) {for (String publicUrlExclude : PUBLIC_URLS_EXCLUDES) {if (url.contains(publicUrlExclude)) {return false;}}return true;}}return false;}
}

总结:

1.要有一个设计良好的RBAC权限模型
2.对于Restful风格的URL权限一定要描述其URL和Method才能够准确鉴权(因为Restful风格的方法存在URL相同,Method不同的情况)。
3.框架的拦截器设计思想。
4.正则表达式的运用,反向生成权限URL的正则表达式。
5.URL放行的匹配可以利用Ant路径表达式来实现(待改进)

以上是工作时的经验所得。如有不正确的地方,还请各位读者指正。

SpringBoot使用拦截器实现Restful URL权限拦截相关推荐

  1. springboot + 拦截器 + 注解 实现自定义权限验证

    springboot + 拦截器 + 注解 实现自定义权限验证 最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定 ...

  2. SpringMVC工作总结001_SpringMVC拦截器(资源和权限管理)

    1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet.     DispatcherServl ...

  3. struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo

    理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...

  4. 使用拦截器或者AOP实现权限管理(OA系统中实现权限控制)

    在开发类似与OA管理系统类型的项目中,经常需要设置到权限管理.例如对某个部门的人员CURD操作,默认是该部门的普通员工是不会有该权限的.但若某个员工升级为该部分的负责人.则此时它就拥有对该部门的CUR ...

  5. Retrofit 在拦截器中加密url 并修改body 参数key-value

    Retrofit 在拦截器中加密url 并修改body 参数key-value 从一个蛋疼的需求说起: URI加密:jjj/ 后面的URI采用AES-CBC-pkcs5padding加密后再base6 ...

  6. Spring Boot笔记-拦截器相关(用户权限方面)

    Spring Boot拦截器的使用 使用注解@Configuration 继承WebMvcConfigurerAdapter 重写addInterceptors添加需要拦截器地址: 运行截图如下: 后 ...

  7. Spring 拦截器流程及多个拦截器的顺序

    拦截器是 Spring MVC 中的组件,它可以在进入请求方法前做一些操作,也可以在请求方法后和渲染视图后做一些事情. 拦截器的定义 SpringMVC 的拦截器只需要实现 HandlerInterc ...

  8. php 请求拦截,解决拦截器对ajax请求的拦截实例详解

    解决拦截器对ajax请求的的拦截 拦截器配置:public boolean preHandle(HttpServletRequest request, HttpServletResponse resp ...

  9. springboot拦截器 跳过_springboot创建拦截器过程图解

    springboot创建拦截器过程图解 这篇文章主要介绍了springboot创建拦截器过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一. ...

最新文章

  1. NS4225D 类音频功率放大器 - 失败告终
  2. python小程序3
  3. gta5结局杀老崔我哭了_都已经2020年了,怎么还有人在买GTA5?
  4. Docker知识4:如何在win10下安装 / 使用ubuntu ?应用WSL2
  5. 入选 Forrester 领导者象限,阿里云 Serverless 产品能力全球第一
  6. 牛客网 【每日一题】5月14日题目 maze
  7. 信息学奥赛一本通(1412:二进制分类)
  8. linux各版本的发布时间,linux服务器-红帽企业Linux各个版本发布时间和内核版本...
  9. 重新安装MySQL5.7.21教程_CentOS6.9安装mysql5.7.21教程
  10. 【Java 异常】try-catch、finally、异常的种类、throws、thorw、自定义异常、断言类
  11. 同时支持mp4/ogg/webm/flv格式的视频播放
  12. 高兴与愉快的心情,难以言语。
  13. java代码发送邮箱_邮件发送 - java代码库 - 云代码
  14. 数据结构-阶段性理解
  15. Android__ListView控件的使用
  16. cmd贪吃蛇(cmd贪吃蛇怎么做)
  17. 三星手机不能连接无线网络连接服务器,手机已连接wife但无法访问互联网
  18. 微服务组件之限流器与熔断器
  19. 亚马逊运营经常忽略的买家秀,主图开箱视频的重要性
  20. MyBatis - 批量插入

热门文章

  1. Excel VBA代码示例
  2. MuiPlayer - 一款优秀的 H5 视频播放器框架
  3. 计算机网络与技术课本,高等学校计算机科学与技术教材:计算机网络基础教程...
  4. SQL DML操作之增删改查
  5. matlab 按字母排序,matlab命令大全(按字母排序) 总汇详解最新发布完整珍藏版
  6. linux ssd加速机械硬盘,关于linux:机械硬盘随机IO慢的超乎你的想象
  7. 进程篇——了解Makefile文件
  8. 【考研总结】考研失败后的反省
  9. 域名解析(阿里云二级域名解析)
  10. 如何配置springboot (1) ---彻骨寒风的博客