使用spring的ProxyFactoryBean来实现权限控制

一、创建发帖接口及实现类。

1) IPostService:

package com.jian.service.post;

import com.jian.beans.Post;

public interface IPostService {
	
	void read(Post post);
	void post(Post post);
	void reply(Post post);
	void delete(Post post);

}
2) PostServiceImpl:
package com.jian.service.post.impl;

import java.sql.Date;
import java.text.SimpleDateFormat;
import com.jian.beans.Post;
import com.jian.service.post.IPostService;
import com.jian.util.Container;

/**
 * <p>
 * Title: 帖子服務類
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Company: 找工作ing
 * </p>
 * 
 * @author "xiaolong8"
 * @version 1.00 2012-3-17 "jian"
 */
public class PostServiceImpl implements IPostService {

	@Override
	public void delete(Post post) {
		System.out.println("delete: " + post.getId());
	}

	@Override
	public void post(Post post) {
		System.out.println("post: " + post.getId()+", content:" + post.getContent());
	}

	@Override
	public void read(Post post) {
		System.out.println("read: " + post.getId());
	}

	@Override
	public void reply(Post post) {
		System.out.println("reply: "+post.getId()+", content:"+post.getContent());
	}

}

二、实现MethodInterceptor接口,来拦截对帖子操作的方法(即IPostService里的方法),再增删改查前执行权限认证。

1)PermissionValidator:

package com.jian.security;

import java.util.List;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import com.jian.beans.Role;
import com.jian.beans.User;
import com.jian.util.Container;
import com.jian.util.SysTools;

/**
 * <p>
 * Title: 權限驗證類
 * </p>
 * <p>
 * Description: 用SPRING AOP來實現權限驗證。原理:通過org.springframework.aop.framework.ProxyFactoryBean來創建動態代理對象,實現對要驗證模組的方法進行攔截,來增加權限驗證功能。
 * </p>
 * <p>
 * Company: 找工作ing
 * </p>
 * 
 * @author "xiaolong8"
 * @version 1.00 2012-3-17 jian
 */
public class PermissionValidator implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
//		System.out.println("(被调用方法接口类名: "
//                + invocation.getMethod().getDeclaringClass().getName() + ")");
//        System.out.println("(被调用方法名:" + invocation.getMethod().getName()+ ")");
//        String methodName = invocation.getMethod().getDeclaringClass()
//                .getName() + "." + invocation.getMethod().getName();
//        System.out.println("(被调用方法全名:" + methodName + ")");
        
		SecurityManager securityManager = (SecurityManager)Container.getBean("securityManager");
		User currentUser = SysTools.getInstance().getCurrentUser();
		String currentMethod = invocation.getMethod().getDeclaringClass().getName()
									+ "." + invocation.getMethod().getName();
		/** 通過用戶所執行的函數來判斷權限  */
		if(!securityManager.checkPermission(currentUser, currentMethod)){
			System.out.println("------------------------------------------------------------------------------------------------------------");
			System.out.println("- currentUser:"+currentUser);
			System.out.print("- 不具備權限來執行方法:");
			System.out.print(currentMethod+"(");
			for(int i = 0; i < invocation.getArguments().length; i++){
				if(i != 0){
					System.out.print(", ");
				}
				System.out.print(invocation.getArguments()[i]);
			}
			System.out.println(")");
			System.out.println("------------------------------------------------------------------------------------------------------------");
			return null;
		}
		return invocation.proceed();
	}
	

}

2) SecurityManager:

package com.jian.security;

import java.util.List;
import com.jian.beans.Role;
import com.jian.beans.User;

public class SecurityManager {
	private static SecurityManager me = null;
	
	private SecurityManager(){
	}
	
	synchronized public static SecurityManager getInstance(){
		if(me == null){
			me = new SecurityManager();
		}
		return me;
	}
	
	/** 驗證用戶是否有該方法執行權限
	 * @param user
	 * @param action 用戶執行的函數名
	 * @return
	 */
	public boolean checkPermission(User user, String action){
		Role role = user.getRole();
		List<String> permissionList = role.getPermissionList();
		
		if(permissionList != null){
			return permissionList.contains(action);
		}
		return false;
	}
}

三、配置spring文件:applicationContext.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	
	<bean id="postServiceTarget" class="com.jian.service.post.impl.PostServiceImpl" />
	<bean id="permissionValidator" class="com.jian.security.PermissionValidator" />
	
	<!--為發帖服務提供權限控制-->
	<bean id="postService" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces">
			<value>com.jian.service.post.IPostService</value>
		</property>
		<property name="target" ref="postServiceTarget" />
		<property name="interceptorNames">
			<list>
				<value>permissionValidator</value>
			</list>
		</property>
	</bean>
	
	<!--安全管理器-->
	<bean id="securityManager" class="com.jian.security.SecurityManager" factory-method="getInstance"></bean>
	
	<!--用戶角色配置, 本應在數據庫中讀取并構造角色,為了便于測試,就在這構造幾個供測試用。-->
	<bean id="adminRole" class="com.jian.beans.Role">
		<constructor-arg type="int" value="0" />
		<constructor-arg type="java.lang.String" value="管理員" />
		<constructor-arg type="java.util.List">
			<list>
				<value>com.jian.service.post.IPostService.delete</value>
				<value>com.jian.service.post.IPostService.post</value>
				<value>com.jian.service.post.IPostService.read</value>
				<value>com.jian.service.post.IPostService.reply</value>
			</list>
		</constructor-arg>
	</bean>
	<bean id="userRole" class="com.jian.beans.Role">
		<constructor-arg type="int" value="1" />
		<constructor-arg type="java.lang.String" value="用戶" />
		<constructor-arg type="java.util.List">
			<list>
				<value>com.jian.service.post.IPostService.post</value>
				<value>com.jian.service.post.IPostService.read</value>
				<value>com.jian.service.post.IPostService.reply</value>
			</list>
		</constructor-arg>
	</bean>
	<bean id="visitorRole" class="com.jian.beans.Role">
		<constructor-arg type="int" value="9" />
		<constructor-arg type="java.lang.String" value="訪客" />
		<constructor-arg type="java.util.List">
			<list>
				<value>com.jian.service.post.IPostService.read</value>
			</list>
		</constructor-arg>
	</bean>

</beans>


四、 测试。

1) 测试类,PostServiceImplTest:

package test.com.jian.service.post.impl;

import org.junit.Before;
import org.junit.Test;
import com.jian.beans.Post;
import com.jian.beans.Role;
import com.jian.beans.User;
import com.jian.service.post.IPostService;
import com.jian.util.Container;
import com.jian.util.SysTools;

public class PostServiceImplTest {
	IPostService postService = (IPostService)Container.getBean("postService");
	Post post = new Post((int)System.currentTimeMillis(), "miss 03", Post.TYPE_POST);
	
	@Before
	public void setup() {
		/** 構建各種用戶 */
		Role adminRole = (Role)Container.getBean("adminRole");
		Role userRole = (Role)Container.getBean("userRole");
		Role visitorRole = (Role)Container.getBean("visitorRole");
		
//		SysTools.getInstance().setCurrentUser(new User(0, "jian", adminRole));
		/** 用普通用戶來進行測試 */
		SysTools.getInstance().setCurrentUser(new User(0, "jian", userRole));
//		SysTools.getInstance().setCurrentUser(new User(0, "jian", visitorRole));
	}
	
	@Test
	public void testRead(){
		postService.read(post);
	};

	@Test
	public void testPost() {
		postService.post(post);
	}

	@Test
	public void testReply(){
		postService.reply(post);
	};
	
	@Test
	public void testDelete(){
		postService.delete(post);
	};
	
}

2) 测试结果:

read: 1918217734
post: 1918217762, content:miss 03
reply: 1918217764, content:miss 03
------------------------------------------------------------------------------------------------------------
- currentUser:{id:0, name:jian, role:{id:1, name:用戶, permissionList:{com.jian.service.post.IPostService.post,com.jian.service.post.IPostService.read,com.jian.service.post.IPostService.reply}}}
- 不具備權限來執行方法:com.jian.service.post.IPostService.delete({id: 1918217767, content: miss 03, type: POST})
------------------------------------------------------------------------------------------------------------

五、其他相关类。

1) 各种bean:

1)) 帖子bean:

Post:

package com.jian.beans;

/**
 * <p>
 * Title: 貼子組件
 * </p>
 * <p>
 * Description: 帖子組件,有兩類:發表帖、回覆帖
 * </p>
 * <p>
 * Company: 找工作ing
 * </p>
 * 
 * @author "xiaolong8"
 * @version 1.00 2012-3-17 "jian"
 */
public class Post {
	/** 發表帖 */
	public static final String TYPE_POST = "POST";
	/** 回覆帖 */
	public static final String TYPE_REPLY = "REPLY";
	private int id;
	private String content;
	private String type;
	
	public Post(int id, String content, String type) {
		this.id = id;
		this.content = content;
		this.type = type;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer();
		buf.append("{id: ").append(id).append(", content: ").append(content)
			.append(", type: ").append(type).append("}");
		return buf.toString();
	}
}

2)) 用户bean:

User:

package com.jian.beans;

public class User {
	private Integer id;
	private String name;
	private Role role;
	
	public User(Integer id, String name, Role role) {
		this.id = id;
		this.name = name;
		this.role = role;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Role getRole() {
		return role;
	}
	public void setRole(Role role) {
		this.role = role;
	}
	
	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("{id:"+id).append(", name:").append(name).append(", role:")
		 	.append(role).append("}");
		return buffer.toString();
	}
}
Role:

package com.jian.beans;

import java.util.List;

public class Role {
	private int id;
	private String name;
	List<String> permissionList;
	
	public Role(int id, String name, List<String> permissionList) {
		this.id = id;
		this.name = name;
		this.permissionList = permissionList;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<String> getPermissionList() {
		return permissionList;
	}
	public void setPermissionList(List<String> permissionList) {
		this.permissionList = permissionList;
	}
	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer();
		buf.append("{id:").append(id).append(", name:").append(name).append(", permissionList:");
		
		int iMax = permissionList.size() - 1;
		buf.append("{");
		if(iMax >= 0 ){
			for (int i = 0; ; i++) {
				buf.append(permissionList.get(i));
				if(i == iMax){
					break;
				}
				buf.append(",");
			}
		}
		buf.append("}");
		
		buf.append("}");
		return buf.toString();
	}
}

2) 工具类:

SysTools:

package com.jian.util;

import com.jian.beans.Role;
import com.jian.beans.User;

public class SysTools {
	private static SysTools me = null;
	private User currentUser;
	
	private SysTools(){
	}
	
	synchronized public static SysTools getInstance(){
		if(me == null){
			me = new SysTools();
		}
		return me;
	}

	
	public void setCurrentUser(User currentUser) {
		this.currentUser = currentUser;
	}

	/** 獲取當前操作的用戶
	 * @return
	 */
	public User getCurrentUser(){
		if(currentUser == null){
			//session 等地方獲取到當前用戶
		}
		return currentUser;
	}
}
Container:

package com.jian.util;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Container {
    /** spring配置文件 * */
	private static final String SPRING_CONFIG = "applicationContext.xml";
	private static ApplicationContext ctx = null;
	
	static{
		ctx = new ClassPathXmlApplicationContext(SPRING_CONFIG);
	}

	/** 獲取bean
	 * @param id bean id
	 * @return
	 */
	public static Object getBean(String id){
		return ctx.getBean(id);
	}
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值