一、创建发帖接口及实现类。
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);
}
}