Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I not getting Spring Security Login Error Messages?

Using Spring Security 3 along with Struts 2 and Tiles 2, I have a login page that appears when it is supposed to and performs the login as expected -- however when I enter bad user credentials I am returned to the login page with no information about what went wrong. I've checked all my configuration parameters and I can't see where the problem is.

My Spring Security XML config is as follows:

 <http auto-config="true" use-expressions="true">
    <intercept-url pattern="/" access="permitAll" />
    <intercept-url pattern="/css/**" access="permitAll" />
    <intercept-url pattern="/images/**" access="permitAll" />
    <intercept-url pattern="/js/**" access="permitAll" />
    <intercept-url pattern="/public/**" access="permitAll" />
    <intercept-url pattern="/home/**" access="permitAll" />
    <intercept-url pattern="/user/**" access="hasRole('AUTH_MANAGE_USERS')" />
    <intercept-url pattern="/group/**" access="hasRole('AUTH_MANAGE_USERS')" />
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <access-denied-handler error-page="/403.html"/>
    <form-login  login-page="/public/login.do" always-use-default-target="false"/>
    <logout invalidate-session="true" logout-success-url="/public/home.do"/>
</http>

My Struts Action looks like this:

<package name="public" namespace="/public" extends="secure">
    <action name="login">
        <result name="success" type="tiles">tiles.login.panel</result>
        <result name="input" type="tiles">tiles.login.panel</result>
        <result name="error">/WEB-INF/jsp/error.jsp</result>
    </action>
    <action name="logout">
        <result name="success" type="redirect">/j_spring_security_logout</result>
    </action>
</package>

And the login.jsp page (part of the tile) looks for the exception from Spring Security...

<c:if test="${not empty param.login_error}">
   <span class="actionError">
   Your login attempt was not successful, try again.<br/><br/>
        Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.
  </span>
</c:if>
<form id="loginForm" name="loginForm" action="/j_spring_security_check" method="post">
  ...
</form>

Can anyone tell me what I am missing? Thanks in advance for any/all replies.

like image 216
Griff Avatar asked Feb 27 '23 02:02

Griff


2 Answers

Spring Security doesn't set param.login_error automatically. You need to do it manaully as follows:

<form-login  
    login-page="/public/login.do" 
    authentication-failure-url = "/public/login.do?login_error=1"
    always-use-default-target="false"/>
like image 66
axtavt Avatar answered Mar 07 '23 13:03

axtavt


One suggestion for helping with the conversion of error messages like in the final comment is to use an AuthenticationFailureHandler to map different exception types to different error codes that the ui-layer code can lookup unique messages for. It looks like:

<security:form-login login-page="/login" 
    authentication-failure-handler-ref="authenticationFailureHandler"/>

<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
    <property name="defaultFailureUrl" value="/login?reason=login_error"/>
    <property name="exceptionMappings">
        <map>
        <entry><key><value>org.springframework.security.authentication.LockedException</value></key>
            <value>/login?reason=user_locked</value></entry>

            <entry><key><value>org.springframework.security.authentication.DisabledException</value></key>
            <value>/login?reason=user_disabled</value></entry>

            <entry><key><value>org.springframework.security.authentication.AuthenticationServiceException</value></key>
            <value>/login?reason=connection</value></entry>
        </map>
    </property>
</bean>
like image 41
Robert MacDonald Avatar answered Mar 07 '23 13:03

Robert MacDonald