Почему я не получаю сообщения об ошибках входа в Spring Security?

Используя Spring Security 3 вместе со Struts 2 и Tiles 2, у меня есть страница входа в систему, которая появляется, когда это предполагается, и выполняет вход в систему, как ожидалось, однако, когда я ввожу неверные учетные данные пользователя, я возвращаюсь на страницу входа без информации о что пошло не так. Я проверил все параметры конфигурации и не вижу, в чем проблема.

Моя XML-конфигурация Spring Security выглядит следующим образом:

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

Мое действие Struts выглядит так:

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

И страница login.jsp (часть плитки) ищет исключение из 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>

Может ли кто-нибудь сказать мне, что мне не хватает? Заранее спасибо за любой/все ответы.


person Griff    schedule 07.10.2010    source источник


Ответы (2)


Spring Security не устанавливает param.login_error автоматически. Вам нужно сделать это вручную следующим образом:

<form-login  
    login-page="/public/login.do" 
    authentication-failure-url = "/public/login.do?login_error=1"
    always-use-default-target="false"/>
person axtavt    schedule 07.10.2010
comment
Идеально. Спасибо! Я знал, что это что-то в конфиге, которого мне не хватало. К сожалению, SPRING_SECURITY_LAST_EXCEPTION выдает очень техническую ошибку, которую я не могу показать пользователю. Причина: локальный: 10389; вложенным исключением является javax.naming.CommunicationException: localhost: 10389 [Корневое исключение — java.net.ConnectException: в соединении отказано: подключение]. -- потому что я аутентифицируюсь по LDAP. Есть ли более значимое сообщение, которое я могу представить пользователю, или просто придерживаться неверного идентификатора пользователя или пароля?? - person Griff; 07.10.2010
comment
@Griff: я думаю, что Bad user id or password лучше по соображениям безопасности, чтобы злоумышленник не мог видеть, что не так. - person axtavt; 07.10.2010
comment
Странный. Документы Spring говорят, что по умолчанию используется /spring_security_login?login_error, который будет автоматически обрабатываться генератором страницы автоматического входа... Может ли он работать с HTML (а не с JSP)? - person OhadR; 23.08.2012
comment
@OhadR: Если вы установите пользовательский login-page, автоматический генератор страницы входа в систему все равно не будет работать. - person axtavt; 23.08.2012

Одно из предложений для помощи в преобразовании сообщений об ошибках, как в последнем комментарии, состоит в том, чтобы использовать AuthenticationFailureHandler для сопоставления разных типов исключений с разными кодами ошибок, для которых код уровня пользовательского интерфейса может искать уникальные сообщения. Это выглядит как:

<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>
person Robert MacDonald    schedule 26.04.2013