為Spring Security添加IP限制功能
項目中要為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.aygfsteel.com/taochen1984/articles/310072.html中的說明自定義Spring Security的一些組件:
- 擴展WebAuthenticationDetails,保存request為一個屬性
- 擴展WebAuthenticationDetailsSource,設置clazz為上面擴展出來的WebAuthenticationDetails修改spring security配置文件,添加以下bean:
<bean id="authenticationProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationDetailsSource" ref="authenticationDetailsSource" /> <property name="authenticationManager" ref="authenticationManager" /> <property name="filterProcessesUrl" value="/j_spring_security_check" /> <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" /> <property name="authenticationFailureHandler" ref="authenticationFailureHandler" /> </bean> <bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <property name="defaultTargetUrl" value="/loginsuccess.jsp" /> </bean> <bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/admin.jsp?error=1" /> </bean> <bean id="authenticationDetailsSource" class="javacommon.security.springsecurity.CustomWebAuthenticationDetailsSource"/> <bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <property name="loginFormUrl" value="/admin.jsp" /> <property name="forceHttps" value="false" /> </bean>
取消s:http的auto-config屬性,將自定義的authenticationProcessingFilter設置為FORM_LOGIN_FILTER:
<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/
posted on 2010-10-11 17:24 gembin 閱讀(3936) 評論(0) 編輯 收藏 所屬分類: Spring