【原创】基于SpringMVC的注解式权限控制--转载请注明出处
来源:互联网 发布:数据库高级编程 编辑:程序博客网 时间:2024/05/21 22:21
1. 开发目标
在Shiro的权限分配中,存在@RequiresPermissions注解进行权限的控制,该注解规定了所进行了注解的方法,只能被具有某些权限的人进行访问,且权限之间为&的关系。这个权限控制是不符合我们所需要的权限控制需求的。(我们所需要的是具有某些权限之一的用户可以访问,同时具有这些权限的子权限也可以访问与具有这些权限本身和其父权限才能进行访问的这两种情况区分开)。
我们在该博客中所描述的权限控制,是一种类似于Shiro的注解式权限控制。做到使用@ExistPermissions和@HasPermissions来进行权限控制的目的。
2. 配置拦截器配置
配置一个类为SpringMVC的拦截器时,只需要在SpringMVC.xml中添加如下代码即可:
<mvc:interceptors> <mvc:interceptor> <!--默认拦截的连接--> <mvc:mapping path="/**"/> <!--不拦截的连接--> <mvc:exclude-mapping path="/user/login.do"/> <bean class="com.xxx.security.filter.SecurityFilter"></bean> </mvc:interceptor> <mvc:interceptor></mvc:interceptors>
其中接口preHandle中的代码会在访问到controller层接口前运行,而afterCompletion与postHandle接口则是在controller层运行完毕后,才会运行代码。因此我们在进行权限处理时,要将权限控制代码写在preHandle方法中。在上述XML配置中,将SecurityFilter 类作为拦截器进行了处理。这个拦截器需要先实现接口HandlerInterceptor 。在该接口中有三个方法,分别为afterCompletion,postHandle,preHandle。
3. 注解配置
在这里我们还需要定义两个注解@ExistPermissions和@HasPermissions。
/** * * @author Administrator * 该注解用于进行对权限的控制, * 当用户的权限中存在该权限或改权限的子权限时,则予以放行 * 相关代码需查看SecurityFilter */@Target(value={ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface ExistPermissions {/** * 可以访问所进行注解的权限的数组对象, * 当具有该数组对象中任意权限的子权限时,均可以进行访问 */String[] permissions();}
/** * * @author Administrator * 该注解用于进行对权限的控制, * 必须在用户持有某些权限中的一个时,才则予以放行 * 相关代码需查看SecurityFilter */@Target(value=ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface HasPermissions {/** * 可以访问所进行注解的权限的数组对象, * 当具有该数组对象中的任意一个权限时,可以进行访问 */String[] permissions();}我们在这两个注解中分别定义了一个方法permissions,这个方法返回类行为String[],用于进行多权限的处理。这样我们就可以一次性对多个权限进行判断。@Target注解定义了这个方法可以用在那些地方,@Retention注解定义了这个方法在什么时候进行使用。
4. preHandle方法
@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
}在方法preHandle 中有三个参数,request,response,handler。前两个参数大家都是十分熟悉的,不做描述,重点在于第三个参数handler。
handler对象是一个object对象,因此,我们需要先通过handler.getclass()方法来查看这个方法的具体类型。
经过
system.out.println(handler.getclass());
可以发现这个对象本身的类型是
org.springframework.web.method.HandlerMethod
那么此时,我们对这个对象进行强制转换,将其强转为它本身的类型。
5. HandlerMethod 类
HandlerMethod,见名知意,这是一个与method相关类,这个类是SpringMVC中定义的一个用于承载一个方法的相关信息的类。我们可以通过这个类的实例来获取该所进行@requestMapping注解的方法的相关信息。
我们所需要使用的部分为注解部分的内容。从HandlerMethod中获取我们所需要的@HasPermissions 注解,然后从注解中获得所我们要进行验证的权限的字符串。
HasPermissions hasPermissions = handlerMethod.getMethodAnnotation(HasPermissions.class);for(String permission : hasPermissions.permissions()){}
6. preHandle方法逻辑处理
当然,用类似的方法,我们也可以获取这个方法上的其他注解,如requestMapping注解。
@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//获取用户权限信息列表UserInfo user = (UserInfo) request.getSession().getAttribute("userInfo");if(user == null){return false ;}Set<String> permissions = user.getPermissions();//获取相应权限注解信息HandlerMethod handlerMethod = (HandlerMethod) handler;//验证用户是否持有其中一个权限HasPermissions hasPermissions = handlerMethod.getMethodAnnotation(HasPermissions.class);boolean hasPer = false;if(hasPermissions != null){for(String permission : hasPermissions.permissions()){if(this.hasPermission(permissions, permission)){hasPer = true;break;}}}else{hasPer = true;}//验证用户是否持有其中一个权限,或者其中一个权限的子权限ExistPermissions existPermissions = handlerMethod.getMethodAnnotation(ExistPermissions.class);boolean existPer = false;if(existPermissions != null){for(String permission : existPermissions.permissions()){if(this.hasPermission(permissions, permission)){existPer = true;break;}}}else{existPer = true;}if(hasPer && existPer){return true;}else{System.out.println("用户 "+user.getUserName()+" 越权访问:"+request.getRequestURL().toString());return false;}}
/** * 验证用户是否持有一个权限,或者一个权限的子权限 * @param permissions * @param permission * @return */public boolean hasPermission(Set<String> permissions, String permission){for(String userPermission : permissions){if(permission.substring(0, userPermission.length()).equals(userPermission)){return true;}}return false;}
/** * 验证用户是否持有一个权限 * @param permissions * @param permission * @return */public boolean existPermission(Set<String> permissions, String permission){for(String userPermission : permissions){if(userPermission.substring(0, permission.length()).equals(permission)){return true;}else if(permission.substring(0, userPermission.length()).equals(userPermission)){return true;}}return false;}
- 【原创】基于SpringMVC的注解式权限控制--转载请注明出处
- Apache2.4权限配置(原创帖-转载请注明出处)
- Core Aduio API--Vista中音量控制的新特点(原创,转载请注明出处)
- Discuz的安装 (原创帖,转载请注明出处)
- 尊重原创,转载请注明出处
- Vista中应用程序需要Administrator权限,自动提示用户需要管理员权限的方法 (原创,转载请注明出处)
- 转载请注明出处
- 关于原始输入--XP新技术(原创,转载请注明出处)
- [原创]WCF入门级使用教程(转载请注明出处)
- S3C2450自动升级[原创作品,转载请注明出处]
- S3C2450自动升级[原创作品,转载请注明出处]
- LAMP环境搭建 (原创帖,转载请注明出处)
- 查看/关闭SElinux (原创帖,转载请注明出处)
- 文章为原创,转载请注明出处,欢迎评论。
- Vista中服务运行与NT5的差别(原创,转载请注明出处)
- 【原创】在java下实现的平衡二叉树--转载请注明出处
- 引用请注明出处和转载请注明出处?我的看法
- 基于RTP的音视频封装和同步方案设计图案【转载请注明出处】
- adb shell input命令与截屏命令解释说明
- 《Android源码设计模式解析与实战》读书笔记(二十四)——桥接模式
- 51nod1350 斐波那契表示 找规律+递归
- 连号区间数
- JAVAEE开发——网上购物子系统(五)
- 【原创】基于SpringMVC的注解式权限控制--转载请注明出处
- Error:(1, 0) Minimum supported Gradle version is 3.3. Current version is 2.14.1.
- [Swift]iOS开发:简易版PDF阅读器
- 零基础入门深度学习(1)
- Java不同类型的算数运算规则
- 日期解析函数
- CSDN日报20170609 ——《我成为程序员是别无选择,但之后却又别有洞天》
- BeanUtils.populate的作用-注册页面
- HDU4857 (7/600)