假设有这样的需求,某些service中的方法只能让已登录用户或者某些用户访问,这是,如果我们在方法中加入安全机制代码势必会对整个系统产生不小的影响,而且,当安全验证机制改变时,我们不可避免的需要重新修改,编译代码 /
我们可以使用Spring AOP的前置通知功能,在方法执行前切入,根据权限判定是否可以访问受限的方法
受限类:这个类的方法只能以gaoxiang登录的用户访问
package ch6.SimpleAOP.MethodBeforeAdvisor.MethodSafe;
public class SecureBean ...{
public void writeSecureMessage()...{
System.out.println("welcome to secure area");
}
}
public class SecureBean ...{
public void writeSecureMessage()...{
System.out.println("welcome to secure area");
}
}
Userinfo.java
package ch6.SimpleAOP.MethodBeforeAdvisor.MethodSafe;
public class Userinfo ...{
private String username;
private String password;
public Userinfo(String username, String password) ...{
super();
this.username = username;
this.password = password;
}
public String getPassword() ...{
return password;
}
public void setPassword(String password) ...{
this.password = password;
}
public String getUsername() ...{
return username;
}
public void setUsername(String username) ...{
this.username = username;
}
}
public class Userinfo ...{
private String username;
private String password;
public Userinfo(String username, String password) ...{
super();
this.username = username;
this.password = password;
}
public String getPassword() ...{
return password;
}
public void setPassword(String password) ...{
this.password = password;
}
public String getUsername() ...{
return username;
}
public void setUsername(String username) ...{
this.username = username;
}
}
安全管理类:用于缓存用户登录信息
package ch6.SimpleAOP.MethodBeforeAdvisor.MethodSafe;
public class SecurityManager ...{
private static ThreadLocal threadLocal=new ThreadLocal();
public void login(String username,String password)...{
//假设用户登录信息合法
threadLocal.set(new Userinfo(username,password));
}
public void logout()...{
threadLocal.set(null);
}
public Userinfo getLoggedUser()...{
return (Userinfo)threadLocal.get();
}
}
public class SecurityManager ...{
private static ThreadLocal threadLocal=new ThreadLocal();
public void login(String username,String password)...{
//假设用户登录信息合法
threadLocal.set(new Userinfo(username,password));
}
public void logout()...{
threadLocal.set(null);
}
public Userinfo getLoggedUser()...{
return (Userinfo)threadLocal.get();
}
}
通知类:在没有用户登录,没有权限的用户登录,正确用户登录,分别进行提示或者异常产生
package ch6.SimpleAOP.MethodBeforeAdvisor.MethodSafe;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class SecurityAdvice implements MethodBeforeAdvice ...{
private SecurityManager securityManager;
public SecurityAdvice()...{
this.securityManager=new SecurityManager();
}
public void before(Method method, Object[] object, Object target)
throws Throwable ...{
Userinfo user=securityManager.getLoggedUser();
if(user==null)...{
throw new SecurityException("no user login in");
}
else if(user.getUsername().equals("gaoxiang"))...{
System.out.println("gaoxiang loggon on system ,welcome");
}
else...{
throw new SecurityException("access dennied");
}
}
}
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class SecurityAdvice implements MethodBeforeAdvice ...{
private SecurityManager securityManager;
public SecurityAdvice()...{
this.securityManager=new SecurityManager();
}
public void before(Method method, Object[] object, Object target)
throws Throwable ...{
Userinfo user=securityManager.getLoggedUser();
if(user==null)...{
throw new SecurityException("no user login in");
}
else if(user.getUsername().equals("gaoxiang"))...{
System.out.println("gaoxiang loggon on system ,welcome");
}
else...{
throw new SecurityException("access dennied");
}
}
}
测试代码:
package ch6.SimpleAOP.MethodBeforeAdvisor.MethodSafe;
import org.springframework.aop.framework.ProxyFactory;
public class TestMethodSafe ...{
/** *//**
* @param args
*/
public static void main(String[] args) ...{
SecurityManager manager=new SecurityManager();
SecureBean bean=getSecureBean();
try ...{
//没有登陆的情况
bean.writeSecureMessage();
} catch (Exception e) ...{
System.out.println(e);
}
//正确登录的情况
manager.login("gaoxiang", "12345");
bean.writeSecureMessage();
//错误登录情况
try ...{
//没有登陆的情况
manager.login("1111","1111");
bean.writeSecureMessage();
} catch (Exception e) ...{
System.out.println(e);
}
}
public static SecureBean getSecureBean()...{
SecureBean bean=new SecureBean();
ProxyFactory pf=new ProxyFactory();
pf.addAdvice(new SecurityAdvice());
pf.setTarget(bean);
SecureBean proxy=(SecureBean)pf.getProxy();
return proxy;
}
}
import org.springframework.aop.framework.ProxyFactory;
public class TestMethodSafe ...{
/** *//**
* @param args
*/
public static void main(String[] args) ...{
SecurityManager manager=new SecurityManager();
SecureBean bean=getSecureBean();
try ...{
//没有登陆的情况
bean.writeSecureMessage();
} catch (Exception e) ...{
System.out.println(e);
}
//正确登录的情况
manager.login("gaoxiang", "12345");
bean.writeSecureMessage();
//错误登录情况
try ...{
//没有登陆的情况
manager.login("1111","1111");
bean.writeSecureMessage();
} catch (Exception e) ...{
System.out.println(e);
}
}
public static SecureBean getSecureBean()...{
SecureBean bean=new SecureBean();
ProxyFactory pf=new ProxyFactory();
pf.addAdvice(new SecurityAdvice());
pf.setTarget(bean);
SecureBean proxy=(SecureBean)pf.getProxy();
return proxy;
}
}
测试结果:
java.lang.SecurityException: no user login in
gaoxiang loggon on system ,welcome
welcome to secure area
java.lang.SecurityException: access dennied