项目中要为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://www.blogjava.net/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/