}
else
{
System.out.println("auth is null!");
}
}
else
{
System.out.println("ctx is null");
}
userName = SecurityContextHolder.getContext().getAuthentication().toString();
System.out.println("UserName is:");
System.out.println(userName);
System.out.println("++++++++++++++++++");
//输出被拦截的接口的名称
System.out.println(target.getClass().getName());
System.out.println(method.getName());
for(int i=0;i〈args.length;i++)
{
System.out.println("HI:"+(String)args[i]);
//输出传入的字符串参数的值
System.out.println( args[i] .getClass().toString());
}
//
//Logger song = Logger.getLogger(target.getClass()); //得到目标类的logger
//System.out.println("println:"+target.getClass().getName()+" did "+method.getName());
}
}
说明:当接口TestAOPInterface的方法被调用前,WelcomeAdvice类作为此接口的前置通知,其before方法将先于TestAOPInterface的方法(在aoptest.xml中配置了WelcomeAdvice拦截TestAOPInterface的所有方法),在before方法里实现了取得当前会话的Authentication即当前用户的身份。既然取得了用户的登录Id,就可以利用此Id做更细粒度的权限控制及添加系统操作日志(日志需要记录哪个用户调用了此方法),由于acegi的这种授权体系支持到方法级别,可以在Advice中进行更深入的开发-规则引擎的开发。例如在ERP系统中,A库管员和B库管员都可以操作入库单录入功能,但A库管员是原料库库管员,B是成品库库管员,如果成品库库管员录入了原料库物品,则提交入库单操作失败,这样的需求,只提供方法及的授权还不够,可通过开发规则引擎来支持数据级的授权。实现方式可将限制参数于传入的方法实际参数进行比较,如符合规则则继续执行。
如果大家想在业务方法里而不是adVCe类里获得userId,最好是参照上述代码,单独设计一个类封装acegi的调用,以免在业务方法中直接引入acegi的API造成对acegi的过度依赖。
2.4 DataSourceMethodDefinitionSourceEditor类
package com.mysoft.pmi.security;
import org.acegisecurity.intercept.method.MethodDefinitionMap;
import org.acegisecurity.ConfigAttributeEditor;
import org.acegisecurity.ConfigAttributeDefinition;
import Java.util.List;
import Java.util.Iterator;
import Java.util.Map;
import Java.beans.PropertyEditorSupport;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* 〈br〉Title:
* 〈br〉Description:
* 〈br〉Copyright: Copyright.com (c) 2003
* 〈br〉Company:
* History:
* create 2005-11-7 19:02:16
*
* @author youlq
* @version 1.0
*/
public class DataSourceMethodDefinitionSourceEditor extends PropertyEditorSupport{
protected JdbcTemplate jdbcTemplate;
//~ Methods ================================================================
public JdbcTemplate getJdbcTemplate(){
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
public void setAsText(String s) throws IllegalArgumentException{
MethodDefinitionMap source=new MethodDefinitionMap();
List rs;
try{
rs=jdbcTemplate.queryForList(s);
} catch(Exception e){
setValue(source);
e.printStackTrace();
return;
}
if((rs==null)||rs.size()==0){
// Leave value in property editor null
} else{
// Now we have properties, process each one individually
ConfigAttributeEditor configAttribEd=new ConfigAttributeEditor();
for(Iterator iter=rs.iterator();iter.hasNext();){
Map row=(Map)iter.next();
String authority=(String)row.get("AUTHORITY");
String resource=(String)row.get("PROTECTED_RES");
if((null==authority)||(resource==null)){
continue;
}
// Convert value to series of security configuration attributes
configAttribEd.setAsText(authority);
ConfigAttributeDefinition attr=(ConfigAttributeDefinition)configAttribEd .getValue();
// Register name and attribute
source.addSecureMethod(resource, attr);
}
}
setValue(source);
}
}
第三章 测试页面
3.1 登录页面
acegilogin.jsp(将此文件放在web应用的根目录下):
〈%@ page contentType="text/html;charset=GBK" language="Java" %〉
〈%@ page import="org.acegisecurity.ui.AbstractProcessingFilter" %〉
〈%@ page import="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter" %〉
〈%@ page import="org.acegisecurity.AuthenticationException" %〉
〈html〉
〈head〉
〈title〉Login〈/title〉
〈/head〉
〈body〉
〈h1〉Login〈/h1〉
〈%
String login_error=request.getParameter("login_error");
if(login_error!=null){
%〉
〈font color="red"〉
登录失败。原因: 〈%= ((AuthenticationException) session.getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY)).getMessage() %〉
〈/font〉
〈%
}
%〉
〈form action="j_acegi_security_check" method="POST"〉
〈table〉
〈tr〉〈td〉User:〈/td〉〈td〉〈input type='text' name='j_username'〉〈/td〉〈/tr〉
〈tr〉〈td〉Password:〈/td〉〈td〉〈input type='password' name='j_password'〉〈/td〉〈/tr〉





