在我用Spring Security進行安全保護的Spring MVC應用程序中,我必須通過以下方式登錄:一是通過識別特定授權IP列表(不需要用戶/密碼登錄),一個是通過經典登錄。爲此,我構建了一個自定義身份驗證提供程序來驗證IP是否經過授權。如果不是,我希望它重定向到通知用戶的錯誤頁面。ExceptionMappingAuthenticationFailureHandler沒有捕捉到我的異常
在這種情況下,我拋出異常(org.springframework.security.authentication.InsufficientAuthenticationException
),並且我試圖使用ExceptionMappingAuthenticationFailureHandler
來捕捉它並將其重定向到正確的頁面。失敗處理程序將InsufficientAuthenticationException
映射到該頁面,並將BadCredentialsException
映射到另一個錯誤頁面(用於執行經典用戶/密碼登錄和登錄錯誤時)。
我用日誌檢查我實際上是拋出異常。但是,失敗處理程序永遠不會捕獲它;相反,我總是會獲得專門用於BadCredentialsException
的頁面。 如何確保我拋出的異常被失敗處理程序捕獲?
這裏是我的安全context.xml中的摘錄:
<http
auto-config="true"
use-expressions="true">
<form-login
login-page="/pages/login.jsp"
login-processing-url="/j_spring_security_check"
default-target-url="/"
authentication-failure-handler-ref="authenticationFailureHandler" />
</http>
<beans:bean
id="customIPAddressAuthenticationProvider"
class="ch.of.ow.security.CustomIPAddressAuthenticationProvider" />
<beans:bean
id="authenticationFailureHandler"
class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop
key="org.springframework.security.authentication.InsufficientAuthenticationException">
/notValidIP
</beans:prop> <!-- THIS IS THE PAGE I WANT -->
<beans:prop
key="org.springframework.security.authentication.BadCredentialsException">
/pages/login.jsp?login_error=true
</beans:prop> <!-- THIS IS THE PAGE I GET INSTEAD -->
</beans:props>
</beans:property>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customIPAddressAuthenticationProvider" />
<authentication-provider user-service-ref='userDetailsService'>
<password-encoder hash="bcrypt" />
</authentication-provider>
</authentication-manager>
這裏是CustomIPAddressAuthenticationProvider的相關部分:
public class CustomIPAddressAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException, InsufficientAuthenticationException {
if (!authentication.getPrincipal().equals("") || !authentication.getCredentials().equals("")) {
// if the user did provide a username/password, skip to the next
// authentication provider, as he will want to log in with his
// credentials instead of his IP
return null;
}
WebAuthenticationDetails wad = null;
String userIPAddress = null;
boolean isAuthenticatedByIP = false;
// Get the IP address of the user tyring to use the site
wad = (WebAuthenticationDetails) authentication.getDetails();
userIPAddress = wad.getRemoteAddress();
// Check if the user is authorized
isAuthenticatedByIP = ipIsAuthorized(userIPAddress); //the ipIsAuthorized does its stuff well
// Authenticated, the user's IP address is authorized
if (isAuthenticatedByIP) {
List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
Authentication result = new UsernamePasswordAuthenticationToken("xxxxxxxxx", "yyyyyyyyy", grantedAuths);
return result;
} else {
System.out.println("Going to throw InsufficientAuthenticationException");
throw new InsufficientAuthenticationException(userIPAddress);
}
}
}
而且我注意到,如果我刪除的第二映射失敗處理程序,我只留下它:
<beans:prop
key="org.springframework.security.authentication.InsufficientAuthenticationException">
/notValidIP
</beans:prop>
然後我s即,如果我嘗試使用不可信IP訪問,我會從/j_spring_security_check
獲得HTTP Status 401 - Authentication Failed: Bad credentials
。所以確實是這種例外。我是否可能在錯誤的地方拋出我的例外?在身份驗證提供程序中引發異常是否意味着在鏈中觸發了更高的憑證異常?
在此先感謝您提供的任何建議。