在struts2.3.4.1中使用注解、反射、拦截器实现基于方法的权限控制
权限控制是每一个系统都应该有的一个功能,有些只需要简单控制一下就可以了,然而有些却需要进行更加深入和细致的权限控制,尤其是对于一些MIS类系统,基于方法的权限控制就更加重要了。
用反射和自定义注解来实现基于struts2的方法级别的权限控制的主要思想是这样的。
1、先定义一个用于识别在进行action调用的时候标注该方法调用是否需要权限控制,需要什么样的权限的注解类。该注解类一般会包括两个属性,一个是需要的权限,一个是对应的action模块。
2、然后就是在需要进行权限控制的action方法上加上该注解类,并标明其应该拥有的权限和对应的action。这样一来在进行action调用的时候可以实现一个自己定义的interceptor来拦截所有的请求,这样在拦截到请求的时候就可以通过ActionInvocation获取到对应的action类的类文件和对应请求的方法名称,然后利用反射来取得action类文件里面对应的请求方法Method,这样就可通过该Method来判断其是否拥有对应的权限控制注解,即看其是否需要进行权限控制,如果需要进行权限控制,就取得该注解并取得其对应的action名称和需要的权限,然后通过session取得当前的用户,并判断当前用户是否拥有对应的某种权限,如果其拥有该权限则继续往下执行,否则,转到自己处理无权限的机制上去。
下面是一段示例代码:
1、定义一个注解,权限配置
package com.ljq.action;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定义一个注解,权限配置
*
* @author jiqinlin
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authority {
/** 模块 */
String module();
/** 权限值 */
String privilege();
}
2、用于拦截请求判断是否拥有权限的拦截器AuthorityInterceptor
package com.ljq.action;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
* 用于拦截请求判断是否拥有权限的拦截器
*
* @author jiqinlin
*
*/
@SuppressWarnings("serial")
public class AuthorityInterceptor extends AbstractInterceptor {
private static final Logger logger=Logger.getLogger(AuthorityInterceptor.class);
public String intercept(ActionInvocation invocation) throws Exception {
String methodName = invocation.getProxy().getMethod();
Class clazz=invocation.getAction().getClass(); //获取类对象
Method currentMethod = clazz.getMethod(methodName);
//检查Action类AnnotationTest是否含有@Authority注解
if (currentMethod.isAnnotationPresent(Authority.class)) {
// 从session里取得当前的用户
String currentUser = (String) ServletActionContext.getRequest()
.getSession().getAttribute("currentUser");
// 取得权限验证的注解
Authority authority = currentMethod.getAnnotation(Authority.class);
// 取得当前请求的注解的action
String module = authority.module();
// 取得当前请求需要的权限
String privilege = authority.privilege();
/**
* 然后可以在此判断当前用户是否拥有对应的权限,如果没有可以跳到指定的无权限提示页面,
* 如果拥有则可以 继续往下执行。
* if (拥有对应的权限) { return invocation.invoke(); }
* else { return "无权限"; }
*/
logger.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
logger.info("用户["+currentUser+"]在"+new SimpleDateFormat("yyyy-MM-dd hh24:mm:ss").format(new Date())
+"调用了["+clazz.getName()+"]类的["+methodName+"]方法,所在模块["+module+"],拥有权限["+privilege+"]。");
logger.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
}
return invocation.invoke();
}
}
3、需要进行权限控制的Action
package com.ljq.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
@Namespace(value="/")
@Results(value = {
@Result(name ="success", location = "/index.jsp"),
@Result(name ="add", location = "/index.jsp"),
})
@Action(value="action")
public class AnnotationAction extends ActionSupport{
//访问路径:http://localhost:8083/struts2_annotation_auth/action!list.htm
@Authority(module="annotation", privilege="list")
public String list() throws Exception {
System.out.println("-------execute---------");
return SUCCESS;
}
//访问路径:http://localhost:8083/struts2_annotation_auth/action!add.htm
@Authority(module = "annotation", privilege = "add")
public String add() {
System.out.println("-------test---------");
return "add";
}
}
4、在struts2的配置文件里面配置自定义的权限控制拦截器
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!--个人发现2.3.4.1注解该项必须配置,否则会有问题,如拦截器无效等。-->
<constant name="struts.convention.default.parent.package" value="default-package" />
<!-- 可选配置项 -->
<!-- 是否支持方法动态调用,即action名!方法名,如user!addUser.action调用user.action中的addUser方法.
不建议使用,这种方法安全性较差
<constant name="struts.enable.DynamicMethodInvocation" value="false" />-->
<!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->
<constant name="struts.devMode" value="true" />
<!-- 指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
<constant name="struts.i18n.encoding" value="UTF-8" />
<!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 -->
<constant name="struts.action.extension" value="htm" />
<!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->
<constant name="struts.serve.static.browserCache" value="false" />
<!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 -->
<constant name="struts.configuration.xml.reload" value="true" />
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
<!-- 配置log4j的日志级别 -->
<!-- <constant name="log4j.logger.org.apache.struts2.convention" value="DEBUG" /> -->
<package name="default-package" extends="convention-default" abstract="true">
<!-- 定义拦截器 -->
<interceptors>
<!-- 申明自定义的权限控制拦截器 -->
<interceptor name="authorityInterceptor" class="com.ljq.action.AuthorityInterceptor" />
<!-- 把自定义的权限控制拦截器和默认的拦截器栈加到新的自定义的拦截器栈 -->
<interceptor-stack name="myInterceptors">
<interceptor-ref name="timer" />
<interceptor-ref name="authorityInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<!-- 指定新的自定义的拦截器栈为默认的拦截器栈,这样自定义的权限控制拦截器就可以发挥作用了 -->
<default-interceptor-ref name="myInterceptors"></default-interceptor-ref>
</package>
</struts>
访问http://localhost:8083/struts2_annotation_auth/action!list.htm,执行结果如下:
[INFO ] [2012-11-29 15:33:26 681]-com.ljq.action.AuthorityInterceptor.44[http-8083-1] - ++++++++++++++++++++++++++++++++++++++++++++++++++++++
[INFO ] [2012-11-29 15:33:26 682]-com.ljq.action.AuthorityInterceptor.45[http-8083-1] - 用户[null]在2012-11-29 0324:33:26调用了[com.ljq.action.AnnotationAction]类的[list]方法,所在模块[annotation],拥有权限[list]。
[INFO ] [2012-11-29 15:33:26 682]-com.ljq.action.AuthorityInterceptor.47[http-8083-1] - ++++++++++++++++++++++++++++++++++++++++++++++++++++++
-------execute---------
[INFO ] [2012-11-29 15:33:27 441]-com.opensymphony.xwork2.interceptor.TimerInterceptor.42[http-8083-1] - Executed action [//action!list] took 765 ms.
访问http://localhost:8083/struts2_annotation_auth/action!add.htm,执行结果如下:
[INFO ] [2012-11-29 15:33:53 604]-com.ljq.action.AuthorityInterceptor.44[http-8083-1] - ++++++++++++++++++++++++++++++++++++++++++++++++++++++
[INFO ] [2012-11-29 15:33:53 605]-com.ljq.action.AuthorityInterceptor.45[http-8083-1] - 用户[null]在2012-11-29 0324:33:53调用了[com.ljq.action.AnnotationAction]类的[add]方法,所在模块[annotation],拥有权限[add]。
[INFO ] [2012-11-29 15:33:53 605]-com.ljq.action.AuthorityInterceptor.47[http-8083-1] - ++++++++++++++++++++++++++++++++++++++++++++++++++++++
-------test---------
[INFO ] [2012-11-29 15:33:53 624]-com.opensymphony.xwork2.interceptor.TimerInterceptor.42[http-8083-1] - Executed action [//action!add] took 20 ms.
在struts2.3.4.1中使用注解、反射、拦截器实现基于方法的权限控制的更多相关文章
- YII2中使用RBAC对模块,控制器,方法的权限控制以及规则的使用
在使用YII2中自带的RBAC时,需要先配置config/web.php: return [ // ... 'components' => [ 'authManager' => [ 'cl ...
- vue中页面跳转拦截器的实现方法
首先对index.js的router进行配置; export default new Router({ routes: [ { path: '/consultancy', name: 'consult ...
- struts2.1笔记03:AOP编程和拦截器概念的简介
1.AOP编程 AOP编程,也叫面向切面编程(也叫面向方面):Aspect Oriented Programming(AOP),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容.利用A ...
- struts2学习笔记(5)---自己定义拦截器
什么是拦截器? struts2中拦截器分为Struts2定义好的拦截器和自己定义的拦截器. 其作用是在一个Action运行之前进行拦截,在Action运行之后又增加某些操作. 实现原理 当请求一个Ac ...
- spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,guava限流,定时任务案例, 发邮件
本文介绍spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,定时任务案例 集成swagger--对于做前后端分离的项目,后端只需要提供接口访问,swagger提供了接口 ...
- springboot中使用过滤器、拦截器、监听器
监听器:listener是servlet规范中定义的一种特殊类.用于监听servletContext.HttpSession和servletRequest等域对象的创建和销毁事件.监听域对象的属性发生 ...
- 在ASP.NET MVC中实现基于URL的权限控制
本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页.这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度 ...
- vue中怎样实现 路由拦截器
vue中怎样实现 路由拦截器(当用户没有登录的时候,跳转到登录页面,已经登录的时候,不能跳转到登录页,除非后台token失效) 在 我们需要实现这样 一个功能,登录拦截 其实就是 路由拦截,首先在定义 ...
- J2EE中的过滤器和拦截器
过滤器和拦截器的相似之处就是拦截请求,做一些预处理或者后处理. 而过滤器和拦截器的区别在于过滤器是相对HTTP请求而言的,而拦截器是相对Action中的方法的. 过滤器:访问web服务器的时候,对一个 ...
随机推荐
- UWP 中的 LaunchUriAsync,使用默认浏览器或其他应用打开链接
古老的 Win32 应用启动其他程序太过方便,以至于一部分开发者都已经不记得 Windows 能通过关联协议的方式通过统一资源定位符(URI)来启动应用程序了. 转到 UWP 后,使用 URI 启动应 ...
- vs2010 C++创建和使用动态链接库(dll)
一.用C++创建动态链接库项目: 1.打开Microsoft Visual Studio 2010,选择File->New->Project. 2.在NewProject中选择Inst ...
- 洛谷P1876开灯
题目描述 有n盏灯,一开始全是关闭的.来n个人, 第一个人把一的倍数的灯开着的关上,关上的打开. 第二个人把二的倍数的灯开着的关上,关上的打开. 第三个人把三的倍数的灯开着的关上,关上的打开. ... ...
- Ant入门使用说明
一.概述 ant 是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.在实际软件开发中,有很多地方可以用到ant. 开发环境: 复制代码 代码如下: S ...
- CF 1093G Multidimensional Queries——线段树(消去绝对值符号)
题目:http://codeforces.com/contest/1093/problem/G 只好看看题解:https://codeforces.com/blog/entry/63877 主要是把绝 ...
- Windows 键盘快捷键概述
在 Windows 中工作时,利用快捷键代替鼠标.可以利用键盘快捷键打开.关闭和导航“开始”菜单.桌面.菜单.对话框以及网页.键盘还可以让您更简单地与计算机交互. 单击一个标题或按 TAB 键可以突 ...
- Ubuntu上kubeadm安装Kubernetes集群
一 创建VM 3台VM,其中一台为master节点,2台work node: 二 安装相关软件 在所有节点上运行: apt-get update apt-get install apt-transpo ...
- 我为什么一直不愿意用bootstrap
做前端有2年多的时间了,知道bootstrap已经很久了. 第一次了解bootstrap是1年前,公司的一次培训中. 当时感到非常的愤怒,因为对框架的了解不够深入产生了这样的一个想法: 怎么会有这种框 ...
- 十五.jQuery源码解析之Sizzle总体结构.htm
Sizzle是一款纯javascript实现的css选择器引擎,它具有完全独立,无库依赖;小;易于扩展和兼容性好等特点. W3C Selectors API规范定义了方法querySelector() ...
- canvas之抒写文字
<canvas id="canvas" width="500" height="400" style="background ...