在框架中使用了acegi,但是割接了一个微软的系统,系统中出现了中文用户名登录,这就造成了问题。
因为之前acegi都是另一个同事负责,现在同事不在,只能自己解决,找到acegi中取得用户名的地方
org.acegisecurity.ui.webapp.authenticationprocessingfilter 中的这段代码
1public authentication attemptauthentication(httpservletrequest request)
2 throws authenticationexception {
3 string username = obtainusername(request);
4 string password = obtainpassword(request);
5
6 if (username == null) {
7 username = "";
8 }
9
10 if (password == null) {
11 password = "";
12 }
13
14 usernamepasswordauthenticationtoken authrequest = new usernamepasswordauthenticationtoken(username, password);
15
16 // place the last username attempted into httpsession for views
17 request.getsession().setattribute(acegi_security_last_username_key, username);
18
19 // allow subclasses to set the "details" property
20 setdetails(request, authrequest);
21
22 return this.getauthenticationmanager().authenticate(authrequest);
23 }
24
取出username后发现是乱码,如果解决这个问题呢?第一个想到的是转码
username=new string(username.getbytes("iso8859-1"),"utf-8");
解决问题,但是这段代码要嵌入到acegi中必须重新编译acegi
上边的办法改动太大,再想办法,想到既然问题是来自编码,看看web.xml的filter发现原因在这
spring的filter是解决编码问题的,但是因为acegi的filter在spring之前,所以编码没有转码。又不能把acegi的filter挪到spring filter之后,这样就有安全问题了。
那就增加一个filter,只过滤登录链接,然后设置一下代替spring的encodingfilter设置一下编码,解决问题
public class encodechnusernamefilter implements filter{
private static final string acegi_security_form_username_key ="j_username";
private static final string acegi_security_form_password_key = "j_password";
public void destroy() {
}
public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {
request.setcharacterencoding("utf-8");
chain.dofilter(request, response);
}
public void init(filterconfig arg0) throws servletexception {
}
}
中文用户名登录问题解决了。
但是另一个问题来了,密码是非明文的md5加密的,需要加密,同样不想更改acegi。
那好吧继续使用filter,看看能否getparameter后再set回去
string password= request.getparameter("j_password");
//这里是个md5加密函数
password = md5(password);
//怎么set进去呢?
request.getparametermap().put("j_password",password);
//启动试一下,异常报错,map不能put,看一下异常,发现这个不是普通的map,是org.apache.catalina.util.parametermap,这个map中有个标志位lock,tomcat不让更改http接收到的值。
//基于不服输的精神,一定要搞定它,呵呵
parametermap map = (parametermap)request.getparametermap();
map.setlock(false);
map.put("j_password",password);
map.setlock(true);
//搞定?不对,编译不通过,发现org.apache.catalina.util.parametermap的jar包是catalina.jar。
把这个包放到lib下编译,通过,运行出向下转型错误,仔细看一下发现request.getparametermap()出来的parametermap.getclass()的id是300多,而接受转型
的parametermap.class.getclass()是6000多,不是一个类啊。想想也对,lib下和tomcat的server/lib下各有一个catalina.jar这个就是两个类了。
eclipse add 外部jar包,直接add上tomcat中的catalina.jar,编译运行,还是有问题,这次是报的classnotfound异常,为什么会这样呢,命名server/lib下有这个jar包,后来想了下明白了。tomcat一定是限定了catalina.jar不能被普通的用户类所直接引用。处于安全性考虑吧。这条路走不通了,回到acegi才发现acegi的配置文件中是可以随意配置autheticationfilter的,自己写一个autheticationfilter,配置进去,不用系统的,解决问题,filter里边怎么写都没问题,爱怎么处理怎么处理,呵呵