How to customize SPRING_SECURITY_LAST_EXCEPTION.message according to the error I get

前端 未结 3 1387
甜味超标
甜味超标 2021-01-03 05:27

I made a login system with Spring Security. This is my spring-security.xml

... 

       

        
相关标签:
3条回答
  • Instead of the authentication-failure-url, you need to use authentication-failure-handler-ref and refer the failure handler bean which you need to create and map different urls (or different params to the same url) to different type of exceptions.

     <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>
    

    There are bunch of other exceptions, mentioned in the docs. Please refer the doc

    EDIT:

    There is an exception for the same, SessionAuthenticationException is thrown typically because the same user has exceeded the number of sessions they are allowed to have concurrent. But this is at container level only and won't work if you have multiple containers.

    <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>
    
    0 讨论(0)
  • 2021-01-03 05:44

    I found this solution, it seems to work.

    Extending SimpleUrlAuthenticationFailureHandler you can send the user to different pages, and print the message you want.

    My main goal wasn't to "override" SPRING_SECURITY_LAST_EXCEPTION.message but was customizing the error message according to the various kind of errors Spring security gives me.

    web.xml

      <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
      </listener>
    

    security-config.xml (just some code)

    session-management

       <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 where you call your own AuthenticationFailureHandler (customFailureHandler)

      <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" />
    

    the bean of your own AuthenticationFailureHandler

     <beans:bean id="customFailureHandler" class="com.springgestioneerrori.controller.CustomAuthenticationFailureHandler"/>
    

    and this is the class implementing SimpleUrlAuthenticationFailureHandler

    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);  
    
        }
    
    }
    

    Hope this can help someone.

    0 讨论(0)
  • 2021-01-03 05:49

    This is an old question, but since the answer marked as correct actually contains a nasty subtle bug it should be noted that the correct solution would be to use built-in ExceptionMappingAuthenticationFailureHandler instead of the CustomAuthenticationFailureHandler suggested in the answer from @mdp.

    0 讨论(0)
提交回复
热议问题