項目中要為SpringSecurity添加IP限制功能,一開始的做法是繼承DaoAuthenticationProvider,在additionalAuthenticationChecks方法中使用WebAuthenticationDetails的getRemoteAddress獲取客戶端IP,然后判斷是否需要限制登錄。
在tomcat上單獨部署時,這樣做一切正常,當使用apache作為前端代理時,發現總是提示IP錯誤,從日志中發現,getRemoteAddress方法總是返回apache的IP。查看WebAuthenticationDetails的源碼發現:
this.remoteAddress = request.getRemoteAddr();
當有代理存在時,request.getRemoteAddr()是不能正確獲取客戶端IP的(http://mrlee23.javaeye.com/blog/510747),
需要使用http header中的x-forwarded-for獲取IP,方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public static final String getIpAddr (final HttpServletRequest request )
throws Exception {
if (request == null) {
throw (new Exception(
"getIpAddr method HttpServletRequest Object is null"));
}
String ipString = request. getHeader("x-forwarded-for");
if (StringUtils. isBlank(ipString ) || "unknown". equalsIgnoreCase(ipString )) {
ipString = request. getHeader("Proxy-Client-IP");
}
if (StringUtils. isBlank(ipString ) || "unknown". equalsIgnoreCase(ipString ))request. getHeader("WL-Proxy-Client-IP");
}
if (StringUtils. isBlank(ipString ) || "unknown". equalsIgnoreCase(ipString ))request. getRemoteAddr();
}
// 多個路由時,取第一個非unknown的ip
final String[] arr = ipString. split(",");
for (final String str : arr ) {
if (!"unknown". equalsIgnoreCase(str ))ipString = str ;
break;
}
}
return ipString ;
}
|
參考http://m.tkk7.com/taochen1984/articles/310072.html中的說明自定義Spring Security的一些組件:
<s:http access-denied-page="/fault.jsp" entry-point-ref="authenticationProcessingFilterEntryPoint">
<s:logout logout-success-url="/admin.jsp" />
<s:remember-me/>
<s:anonymous/>
<s:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" />
</s:http>
from: http://codingmu.ixiezi.com/