在框架中使用了acegi,但是割接了一個微軟的系統,系統中出現了中文用戶名登錄,這就造成了問題。
因為之前acegi都是另一個同事負責,現在同事不在,只能自己解決,找到acegi中取得用戶名的地方
org.acegisecurity.ui.webapp.AuthenticationProcessingFilter 中的這段代碼
1
public 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里邊怎么寫都沒問題,愛怎么處理怎么處理,呵呵