`
234390216
  • 浏览: 10197177 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:461019
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1772134
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395785
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:394006
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678363
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529417
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178996
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:462567
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150282
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66976
社区版块
存档分类
最新评论

反射和注解的妙用——struts2基于方法的权限控制

阅读更多

权限控制是每一个系统都应该有的一个功能,有些只需要简单控制一下就可以了,然而有些却需要进行更加深入和细致的权限控制,尤其是对于一些MIS类系统,基于方法的权限控制就更加重要了。

用反射和自定义注解来实现基于struts2的方法级别的权限控制的主要思想是这样的。

 

1.先定义一个用于识别在进行action调用的时候标注该方法调用是否需要权限控制,需要什么样的权限的注解类。该注解类一般会包括两个属性,一个是需要的权限,一个是对应的action。

 

2.然后就是在需要进行权限控制的action方法上加上该注解类,并标明其应该拥有的权限和对应的action。这样一来在进行action调用的时候可以实现一个 自己定义的interceptor来拦截所有的请求,这样在拦截到请求的时候就可以通过ActionInvocation获取到对应的action类的类文件和对应请求的方法名称,然后利用反射来取得action类文件里面对应的请求方法Method,这样就可通过该Method来判断其是否拥有对应的权限控制注解,即看其是否需要进行权限控制,如果需要进行权限控制,就取得该注解并取得其对应的action名称和需要的权限,然后通过session取得当前的用户,并判断当前用户是否拥有对应的某种权限,如果其拥有该权限则继续往下执行,否则,转到自己处理无权限的机制上去。

 

下面是一段示例代码:

Authority注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authority {

	String action();
	
	String privilege();
	
}

 

 

用于拦截请求判断是否拥有权限的拦截器AuthorityInterceptor:

import java.lang.reflect.Method;
import java.util.Date;

import org.apache.struts2.ServletActionContext;


import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class AuthorityInterceptor implements Interceptor {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4637261955156527951L;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init() {
		// TODO Auto-generated method stub

	}

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		// TODO Auto-generated method stub
		String methodName = invocation.getProxy().getMethod();
		Method currentMethod = invocation.getAction().getClass().getMethod(methodName);
		//如果该方法请求是需要进行验证的时候执行以下逻辑
		if (currentMethod.isAnnotationPresent(Authority.class)) {
//			String currentUser = Util.getCurrentUser(ServletActionContext.getRequest());
			//这里可以从session里面取得当前的用户
			String currentUser = (String)ServletActionContext.getRequest().getSession().getAttribute("currentUser");
			//取得权限验证的注解
			Authority authority = currentMethod.getAnnotation(Authority.class);
			//取得当前请求的注解的action
			String actionName = authority.action();
			//取得当前请求需要的权限
			String privilege = authority.privilege();
			/**
			 * 然后可以在此判断当前用户是否拥有对应的权限,如果没有可以跳到指定的无权限提示页面,如果拥有则可以
			 * 继续往下执行。
			 * ...............
			 * if (拥有对应的权限) {
			 * 		return invocation.invoke();
			 * } else {
			 * 		return "无权限";
			 * }
			 */
			System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
			System.out.println("用户" + currentUser + "在" + new Date() + actionName);
			System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
		}
		return invocation.invoke();
	}

}

 

需要进行权限控制的Action:

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4679109342743365308L;

	@Override
	@Authority(action="test", privilege="find")//请求该方法的时候需要拥有对test的find权限
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		return super.execute();
	}
	
	//请求该方法需要拥有对test的test权限
	@Authority(action="test", privilege="test")
	public String test() {
		return "test";
	}

}

 

 

在struts2的配置文件里面配置自定义的权限控制拦截器:

<!-- 定义拦截器 -->
     <interceptors>
     <!-- 申明自定义的权限控制拦截器 -->
     	<interceptor name="authorityInterceptor" class="com.test.AuthorityInterceptor"/>
     	<!-- 把自定义的权限控制拦截器和默认的拦截器栈加到新的自定义的拦截器栈 -->
     	<interceptor-stack name="myInterceptors">
     		<interceptor-ref name="authorityInterceptors"/>
     		<interceptor-ref name="defaultStack"/>
     	</interceptor-stack>
     </interceptors>
     <!-- 指定新的自定义的拦截器栈为默认的拦截器栈,这样自定义的权限控制拦截器就可以发挥作用了 -->
     <default-interceptor-ref name="myInterceptors"></default-interceptor-ref>

 

25
6
分享到:
评论
17 楼 syhu100200 2013-04-27  
[flash=200,200][url][img][list]
[*]
引用
引用
[b][b][u][u][i][i][i][i][i][i][i][/i][/i][/i][/i][/i][/i][/i][/u][/u][/b][/b]
[/list][/img][/url][/flash]
16 楼 w156445045 2012-03-09  
我做的权限设计,可能比较简单,
用户表里面有个groupid 字段
字段值为1 的是普通用户,2为管理员 3为超级管理员
这种类型,
然后页面进行判断的,根据不同的id值显示不同的页面。

虽然可以猜测,但是我觉得可以再加一个拦截器,不让用户执行相应的方法就可以了,比如只有管理员才能删除。
15 楼 kingpeixin 2011-11-02  
看的有一点点懂,没动手弄过
14 楼 shanjing 2011-11-02  
权限控制应该是页面的可见性和URL的可访问性保持一致的。
前台要通过标签控制,后台通过拦截器过滤都是必须的。
13 楼 csuzm0613 2011-10-29  
qq123zhz 写道
还是配置文件方便一点。。

同问,就教使用配置文件该如何弄呢,望不吝分享...
12 楼 234390216 2011-10-29  
287854442 写道
思路很不错 顶一个 就是有点 复杂了  应该提供一个默认值。

提供一个默认值也挺好的
11 楼 287854442 2011-10-29  
思路很不错 顶一个 就是有点 复杂了  应该提供一个默认值。
10 楼 hiswing 2011-10-28  
Shiro的注释也是如此。
9 楼 234390216 2011-10-28  
qq123zhz 写道
还是配置文件方便一点。。

请教一下,请问配置文件怎样配置可以控制每一个方法的权限呢?是配URL吗?
8 楼 qq123zhz 2011-10-28  
还是配置文件方便一点。。
7 楼 liuyupy 2011-10-27  
做过几乎完全一样的功能,但在系统中并未使用,改成使用配置文件方式来做更加灵活...
在需求未完全确定且存在变更的可能性时,使用注解会很惨.
用来做日志还可以.
6 楼 234390216 2011-10-27  
imp860124 写道
开始在项目里面用Struts2的时候就这样做过,只是当时是用作记录操作日志,但思路和楼主一样。

用作系统日志也挺好的,我也曾经这样用。
5 楼 imp860124 2011-10-27  
开始在项目里面用Struts2的时候就这样做过,只是当时是用作记录操作日志,但思路和楼主一样。
4 楼 energykey 2011-10-27  
重要的是思路。
3 楼 chengpan 2011-10-27  
LZ , 很好
2 楼 234390216 2011-10-27  
youjianbo_han_87 写道
这是一种思路,但为什么不从操作的源头就配置好权限呢? 比如,没有查询权限的用户,根本看不到查询功能。

那是粗粒度的权限控制,虽然那样是可以控制没有权限不能看到相应的查询页面,但是没有权限的用户可以进行猜测,以直接请求URL的方式请求某一无权限的资源。所以我觉得还是这样比较保险一些。我这给的指是针对方法级别的权限控制,真正在实际应用中,肯定是会有粗粒度的权限控制的,也就是说没有相应权限的用户看不到相应的链接和菜单,是会把粗粒度的权限控制和基于方法的权限控制结合起来一起使用的。
1 楼 youjianbo_han_87 2011-10-27  
这是一种思路,但为什么不从操作的源头就配置好权限呢? 比如,没有查询权限的用户,根本看不到查询功能。

相关推荐

Global site tag (gtag.js) - Google Analytics