Java 如何根据我得到的错误定制SPRING\u SECURITY\u LAST\u EXCEPTION.message
我用Spring Security做了一个登录系统。 这是我的spring-security.xmlJava 如何根据我得到的错误定制SPRING\u SECURITY\u LAST\u EXCEPTION.message,java,spring,jsp,spring-mvc,spring-security,Java,Spring,Jsp,Spring Mvc,Spring Security,我用Spring Security做了一个登录系统。 这是我的spring-security.xml ... <session-management invalid-session-url="/login"> <concurrency-control max-sessions="1" expired-url="/login" error-if-maximum-exceeded="true"/> </session-management> &l
...
<session-management invalid-session-url="/login">
<concurrency-control max-sessions="1" expired-url="/login" error-if-maximum-exceeded="true"/>
</session-management>
<form-login
login-page="/login"
default-target-url="/index"
always-use-default-target="true"
authentication-failure-url="/login?error=true"
username-parameter="j_username"
password-parameter="j_password" />
<logout
logout-success-url="/login"
delete-cookies="JSESSIONID"
invalidate-session="true" />
...
。。。
...
因为我有这一行身份验证失败url=“/login?error=true”
我知道如果error
为'true'
则会出现错误:可能是“错误凭据””或“超出了最大会话数””。但我想知道到底是哪个错误造成的
在java类(@controller)中,有没有办法知道Spring给了我什么样的错误消息,以便自定义这些错误消息?您需要使用身份验证失败处理程序ref并引用失败处理程序bean来创建和映射不同的url,而不是身份验证失败url(或同一url的不同参数)设置为不同类型的异常
<form-login
login-page="/login"
default-target-url="/index"
always-use-default-target="true"
authentication-failure-handler-ref="customFailureHandler"
username-parameter="j_username"
password-parameter="j_password" />
<beans:bean id="customFailureHandler"
class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop
key="org.springframework.security.authentication.BadCredentialsException">/url1</beans:prop>
<beans:prop
key="org.springframework.security.authentication.AuthenticationServiceException">/url2</beans:prop>
<beans:prop key="org.springframework.secuirty.authentication.DisabledException">/url3</beans:prop>
</beans:props>
</beans:property>
<beans:property name="defaultFailureUrl" value="/url4" />
</beans:bean>
/url1
/url2
/url3
文档中提到了大量其他例外情况。请参考
编辑:
同一个存在异常,通常会引发SessionAuthenticationException,因为同一用户超过了允许其并发的会话数。但这仅限于容器级别,如果您有多个容器,则不会起作用
<security:session-management session-authentication-strategy-ref="sas"/>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy" >
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="maximumSessions" value="2" />
</bean>
我找到了这个解决方案,它似乎有效 扩展
SimpleRuthenticationFailureHandler
可以将用户发送到不同的页面,并打印所需的消息
我的主要目标不是“覆盖”SPRING\u SECURITY\u LAST\u EXCEPTION.message
,而是根据SPRING SECURITY给我的各种错误定制错误消息
web.xml
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
希望这能对某人有所帮助。这是一个老问题,但由于标记为正确的答案实际上包含一个令人讨厌的微妙错误,因此应该注意,正确的解决方案是使用内置的
异常映射AuthenticationFailureHandler
而不是ans中建议的CustomAuthenticationFailureHandler
wer from@mdp.谢谢你,伙计。不幸的是,如果用户试图同时从许多不同的设备登录(超过了最大会话数),则没有任何特定的例外情况。我应该如何处理这个问题?我不知道我是否已经编辑了答案以包含会话控制。谢谢你。我找到了另一个解决方案并发布了。总之,你的解决方案很好!总体上解决方案相当可靠,但在重写方法中调用setter以在超级方法中发生自定义行为是非常糟糕的做法。将有e整个应用程序的一个CustomAuthenticationFailureHandler
实例,因此在多线程场景中,无法知道会发生什么(在第一个线程执行onAuthenticationFailure
之前,另一个线程可能调用了setDefaultFailureUrl
)。使方法同步将解决问题,但这仍然是相当糟糕的。
<session-management invalid-session-url="/login" session-authentication-error-url="/login" >
<concurrency-control max-sessions="1" expired-url="/login" error-if-maximum-exceeded="true"/>
</session-management>
<form-login
login-page="/login"
default-target-url="/index"
always-use-default-target="true"
authentication-failure-handler-ref="customFailureHandler"
username-parameter="j_username"
password-parameter="j_password" />
<beans:bean id="customFailureHandler" class="com.springgestioneerrori.controller.CustomAuthenticationFailureHandler"/>
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
if(exception.getClass().isAssignableFrom(BadCredentialsException.class)) {
setDefaultFailureUrl("/url1");
}
else if (exception.getClass().isAssignableFrom(DisabledException.class)) {
setDefaultFailureUrl("/url2");
}
else if (exception.getClass().isAssignableFrom(SessionAuthenticationException.class)) {
setDefaultFailureUrl("/url3");
}
super.onAuthenticationFailure(request, response, exception);
}
}