SpringMVC+Spring+Mybatis +Annotation实现方法,按钮级别的细粒度权限控制

2023-10-29

本文转载自:http://blog.csdn.net/ycyk_168/article/details/18456631

随着企业信息化的不断深入,各种各样的信息系统成为提高企业运营及管理效率的必备工具,越来越多的企业核心机密如销售机会、客户资料、设计方案等通过信息系统存储、备案、流转,这些核心资料一旦外泄,势必对企业造成极大损失。科技时代,信息是企业生存的命脉,信息的安全也必然成为企业极度重视的问题。如今,随着各种信息安全措施的实施,信息泄密已经从外部泄漏向内部人员泄漏转移。外部的黑客、病毒要想获取有价值的信息,必须穿透多道防火墙,逃避多重杀毒工具的追杀,再对信息进行筛选才能如愿以偿;而内部人员知道什么信息是有价值的,如果不对信息进行必要的安全防护,企业内部一些有有心人员会十分容易地获取自己所需要的信息资料。

最近的一份调查显示,几乎有一半的各行各业专业人士承认当他们跳槽时会带走资料,包括文件、销售协议和合同清单等各种资料,并将它们告诉下一个老板。调查还发现,八成的职员可以轻松地下载“有竞争力”的资料和信息,然后带到下一份工作中。

信息安全任重而道远。要保证信息系统的安全,需要考虑到很多方面如防火墙、加密传输、防SQL注入等,但很多的安全方案都是从如何把守大门着手的,如身份认证、数字证书,不管是传统的用户名加口令方式还是基于生物特征识别的指纹、视网膜扫描技术,乃至各类电子政务领域常用的USBkey都是在进入系统大门时大做文章,一旦身份识别完成进入大门后,却听之任之,很少再有处理方案。本文重点不在如何进行身份认证,而在身份认证完成后也即进入系统大门后,如何保证用户只在自己有权限的范围内进行操作,而不是可以进行任意功能的操作即系统内部细粒度权限控制解决方案。


常用的权限系统设计模式是以角色为核心的,即角色是具有相同权限的一类人员的集合:

1.     一个角色可以有包含多个操作人员,一个操作人员也可以属于多个角色

2.     一个角色可以具有多个功能的操作权限,一个功能也可以被多个角色所拥有。

在登录时通过查询登录用户所属角色,即可得到个用户的所有功能集合,如下图:



多数业务系统的页面功能菜单设计是以三级为标准的,即一级功能菜单、二级功能菜单、三级功能菜单,通常情况下一二级功能菜单只是用于功能分类,是不具有功能访问地址的,三级菜单才是功能的真正入口,常规权限系统就是通过控制每个人员对应的功能菜单的显示与隐藏来实现权限控制。要实现细粒度权限控制,可在设计功能表时再加入第四层:页面元素,隶属于第三层功能菜单,这些页面元素用来标识功能页面中的每一个功能按钮,如增加、修改、删除、查询都可算是页面元素,在为角色分配权限时,第四层也同样纳入统一权限管理,如果有此页面元素的权限,则页面上就显示该按钮,如果没有此页面元素的功能权限,则该按钮就不会显示出来。


对于没有权限访问的功能或页面除了进行前台的隐藏之外,还需要在后台访问时进行权限的验证,否则操作人员绕开页面直接通过输入URL访问功能就会造成权限漏洞,通过SpringMVC+Annotation的方式可以轻松实现,代码如下:

第一步:创建SpringMVC拦截器,拦截所有需要进行权限验证的功能请求

[html]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. <!-- 开启注解 -->  
  2.     <mvc:annotation-driven/>  
  3.       
  4.       
  5.     <!-- 静态资源访问 -->  
  6.      <mvc:resources location="/static/" mapping="/static/**"/>   
  7.         
  8.      <!-- 拦截器 -->  
  9.       <mvc:interceptors>    
  10.         <!-- 多个拦截器,顺序执行 -->    
  11.         <mvc:interceptor>    
  12.           <!-- 如果不配置或/**,将拦截所有的Controller -->  
  13.            <mvc:mapping path="/**" />   
  14.            <!-- 在Freemarker界面展示之前做一些通用处理   -->  
  15.            <bean class="xx.xxxx.core.web.FreeMarkerViewInterceptor"></bean>    
  16.         </mvc:interceptor>    
  17.     </mvc:interceptors>    


第二步:创建作用于Method级别的Annotation类,用于传入功能ID

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. @Retention(RetentionPolicy.RUNTIME)  
  2. @Target(ElementType.METHOD)  
  3. public @interface Permission {  
  4.   
  5.     /** 
  6.      * 功能ID,该功能ID,对应数据库中的功能ID 
  7.      * @return 
  8.      * @version V1.0.0 
  9.      * @date Jan 13, 2014 4:59:35 PM 
  10.      */  
  11.     String value();  
  12.       
  13. }  
第三步:通过静态常量建立数据库中的功能ID与执行方法的一对一关系

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. public class FuncConstants {  
  2.   
  3.     /** 
  4.      * 系统管理-角色管理-增加角色 
  5.      */  
  6.     public final static String Xtgl_Jsgl_AddJs = "4399d98bb0d84114acb5693081e83bc9";  
  7.     /** 
  8.      * 系统管理 - 部门管理- 部门列表 
  9.      */  
  10.     public final static String Xtgl_Bmgl_BmList = "dbc4bf80f8b6418788b79de204d37932";  
  11.       
  12. }  

第四步:在SpringMVC拦截器中验证权限

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * FreeMarker视图拦截器,页面展示之前做一些通用处理 
  3.  * @version V1.0.0 
  4.  * @date Dec 12, 2013 4:20:04 PM 
  5.  */  
  6. public class FreeMarkerViewInterceptor extends HandlerInterceptorAdapter {  
  7.   
  8.     public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {  
  9.           
  10.     }  
  11.   
  12.     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView view) throws Exception {  
  13.         String contextPath = request.getContextPath();  
  14.         if (view != null) {  
  15.             request.setAttribute("base", contextPath);  
  16.         }  
  17.     }  
  18.     
  19.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  20.           
  21.         //处理Permission Annotation,实现方法级权限控制  
  22.         HandlerMethod method = (HandlerMethod)handler;  
  23.         Permission permission = method.getMethodAnnotation(Permission.class);  
  24.           
  25.         //如果为空在表示该方法不需要进行权限验证  
  26.         if (permission == null) {  
  27.             return true;  
  28.         }  
  29.           
  30.         //验证是否具有权限  
  31.         if (!WebUtil.hasPower(request, permission.value())) {  
  32.             response.sendRedirect(request.getContextPath()+"/business/nopermission.html");  
  33.             return false;  
  34.         }  
  35.         return true;  
  36.           
  37.           
  38.         //注意此处必须返回true,否则请求将停止  
  39.         //return true;  
  40.     }  
  41.   
  42. }  

至此,基于按钮、方法验证的细粒度权限体系完成!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC+Spring+Mybatis +Annotation实现方法,按钮级别的细粒度权限控制 的相关文章

随机推荐

  • 关于浏览器静止音频自动播放的问题

    背景 今天在制作前端页面时 想要给网页加上会自动播放的音乐 但是用audio标签设置音频的自动播放后 即使将autoplay属性设置成true 谷歌等浏览器页面加载完成后也不会自动播放音乐 尝试了各种办法无果 原因 目前 最为流行的浏览器共
  • 求助TCanvas内存无限涨的问题

    求助TCanvas内存无限涨的问题 Delphi Windows SDK API http www delphi2007 net DelphiMultimedia html delphi 20061110220830160 html pro
  • 利用Wireshark分析TCP三次握手

    首先打开 http www baidu com这个网址进行抓包 首先在过滤器中输入 http过滤 找到 GET HTTP 1 1 我们可以看到在出现了三条TCP记录之后才出现了HTTP这也更加相信HTTP是基于TCP协议的 第一次TCP握手
  • uniapp 顶部头部样式

  • 【Python】剑指offer 14:剪绳子

    题目 给你一根长度为n的绳子 请把绳子剪成m段 m和n都是整数 n gt 1并且m gt 1 每段绳子的长度记为k 0 k 1 k m 请问k 0 k 1 k m 可能的最大乘积是多少 例如 当绳子的长度为8时 我们把它剪成长度分别为2 3
  • idea中类存在编译器报错类无法找到,打包正常解决

    步骤 关键在于清掉类在idea的cache 1 刷新maven项目 2 清理idea缓存 3 maven clean install 4 重新bulid 5 如果使用了lombok插件开启之后重新build 6 maven依赖冲突导致
  • Gin微服务框架_golang web框架_完整示例Demo

    Gin简介 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 Gin是一个golang的微框架 封装比较优雅 API友好 源码注释比较明确 具有快速灵活 容错方便等特点 其实对于golang而
  • Haystack 太强了!存 2600 亿图片

    作者 奇伢 来源 奇伢云存储 小文件存储 小文件存储 老生常谈的问题 先聊聊小文件存储重点关注的是什么 以前我们提过 对于磁盘来说 小 io 吃 iops 大块 io 吃吞吐 划重点 小文件的重点是 io 次数 为什么每次提到海量小文件的时
  • 定时器串口收发和空闲中断串口收发+STM32CubeMX

    引言 最近在做串口实验 总结了两种串口收发的方法 第一种是用定时器定的 第二种是使用空闲中断 第一种 使用定时器 具体做法是在串口接收数据时启动定时器 每接收一帧数据要复位定时值以保证定时器不会溢出 根据波特率计算出大概什么时候接收数据完成
  • 保姆级别uni-app使用低功耗蓝牙

    实现方式 本文使用 uni app Vue3 的方式进行开发 以手机app的方式运行 uni app 提供了低功耗蓝牙 的 api 和微信小程序提供的 api 是一样的 所以本文的讲解也适用于微信小程序 本文参考文档 https blog
  • 普中51单片机独立按键原理及源代码

    由于按键是机械弹性按键 具有弹性 在毫秒级别的时间下 按键后有短暂的抖动 转载自江科大自协化51单片机入门教程 如果按键一次用力较轻 按键里的小金属片可能会多次抖动 使得LED闪烁多次 即轻微按一次 小概率出现多次LED闪烁 消除毫秒级别下
  • 设计模式 -- 享元模式(Flyweight Pattern)

    使用共享对象可以有效的支持大量的细粒度对象 应用场景 主要目的是实现对象的共享 即共享池 当系统中对象多的时候可以减少内存的开销 通常与工厂模式一起使用 例如 缓存 对象池 Android中 Message obtain通过重用Messag
  • 如何在ubuntu系统下安装jdk

    由于换了系统 要从新配置下环境 下面说明下如何在ubuntu系统下安装jdk 首先安装eclipse 我是在ubuntu软件中心安装的 3 8版本 比较老 但图省事也就先这样了 然后要从网上下载jdk1 7 3 8版本最多支持到jkd1 7
  • Android 获取屏幕宽高的正确姿势

    前言 在开发时 我们经常需要根据屏幕的宽高来进行对view的适配 无论是自定义view还是andorid自带的一些控件 比如说需要占当前屏幕高度的30 就需要获取到屏幕的宽高 但在获取宽高时我遇到了一些坑 总结如下 获取高度 下面两种方法都
  • C语言:文件读取

    C语言 文件读取 在C语言中 我们可以使用标准库中的文件操作函数来读取和写入文件 本文将介绍如何使用C语言读取文件 首先 我们需要打开一个文件 可以使用fopen 函数来打开文件 该函数需要两个参数 第一个参数为文件名 第二个参数为打开方式
  • 栈的初始化、销毁、出入栈、取栈顶元素

    一 初始化 void SeqStackInit SeqStack stack if stack NULL return stack gt size 0 stack gt capacity 1000 yuan shi da xiaostack
  • csdn 首发最轻松安装教程:关于centos7 centos8 centos9如何安装erlang和对应版本的rabbitmq

    1 前言 最近做毕业设计 自己装了个虚拟机 但通过各种rpm下载包的方式安装erlang和rabbitmq 总是无法启动或启动失败 琢磨了一番 是erlang相关的包依赖没有自动安装 起码得几十个 由于过于麻烦 下面请看图 所以我写了一个r
  • idea远程调试

    目录 1 背景 2 代码 3 idea配置 4 服务端远程开启debug服务 5 远程调试 5 1 服务端 5 2 本地启动 6 注意 1 背景 线上出了问题 我们一般是通过日志来定位问题 在没有日志的情况下 往往定位问题是比较困难的 这时
  • Java基础教程2-安装和配置Eclipse IDE环境

    前面文章介绍了如何安装JDK和设置环境变量 这篇介绍如何安装eclipse IDE IDE是集成开发环境的意思 你应该听说过eclipse是一个开发人员常用的IDE工具 可以这么说 几乎所有的开发人员都会用这个IDE工具来开发 当然市场上有
  • SpringMVC+Spring+Mybatis +Annotation实现方法,按钮级别的细粒度权限控制

    本文转载自 http blog csdn net ycyk 168 article details 18456631 随着企业信息化的不断深入 各种各样的信息系统成为提高企业运营及管理效率的必备工具 越来越多的企业核心机密如销售机会 客户资