Spring Безопасность - нужна ошибка 403, а не перенаправление
Я использую Spring Security 3.0.4. У меня есть куча веб-сервиса, который защищен Spring Security. Когда я обращаюсь к ним как к неавторизованному пользователю, Spring Security перенаправляется на страницу входа. Вместо этого я хочу вернуть HTTP 403 ошибку. Как я могу это достичь?
Вот мой конфиг безопасности:
<http auto-config="false" use-expressions="true" >
<intercept-url pattern="/authorization.jsp" access="permitAll"/>
<intercept-url pattern="/registration.jsp" access="permitAll"/>
<intercept-url pattern="/api/authorization/auth" access="permitAll"/>
<intercept-url pattern="/api/authorization/new" access="permitAll"/>
<intercept-url pattern="/api/accounts/new" access="permitAll"/>
<intercept-url pattern="/app/**" access="permitAll"/>
<intercept-url pattern="/extjs/**" access="permitAll"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/authorization.jsp"
default-target-url="/index.jsp"
authentication-failure-url="/registration.jsp?login_error=1"
always-use-default-target="true"
/>
<logout logout-success-url="/authorization.jsp"
logout-url="/j_spring_security_logout"
invalidate-session="true"/>
</http>
Ответы
Ответ 1
Для конфигурации java вам нужно сделать
http.exceptionHandling().authenticationEntryPoint(alwaysSendUnauthorized401AuthenticationEntryPoint);
Где alwaysSendUnauthorized401AuthenticationEntryPoint является константой класса
public class AlwaysSendUnauthorized401AuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public final void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
LOGGER.debug("Pre-authenticated entry point called. Rejecting access");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
Это отключает поведение по умолчанию Spring (перенаправление неавторизованных запросов в форму входа).
Боковое примечание:
для такого случая код HTTP SC_UNAUTHORIZED (401) является лучшим выбором, чем SC_FORBIDDEN (403).
Ответ 2
Здесь есть статья о spring форумах здесь, в которой описывается, как определить ваше приложение между двумя методами. До сих пор я использую следующий код для защиты своих контроллеров данных:
<bean id="ep403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<sec:http pattern="/data/**" entry-point-ref="ep403" use-expressions="true">
<sec:intercept-url pattern="/**" access="isAuthenticated()"/>
</sec:http>
<bean id="epauth" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login.html"/>
</bean>
<sec:http pattern="/**" entry-point-ref="epauth" use-expressions="true">
<sec:intercept-url pattern="/**" access="isAuthenticated()"/>
</sec:http>
Таким образом, все решение DelegatingAuthenticationEntryPoint в статье, которую я связал, немного больше тяжеловесов, но я думаю, что эта работа тоже прекрасна.
Ответ 3
вам нужно
- Создайте
RequestMatcher
чтобы определить, какие запросы должны получить 403 (AntPathRequestMatcher
может AntPathRequestMatcher
в вашем случае). - Сконфигурируйте
HttpSessionRequestCache
для проверки соответствия и не сохраняйте эти страницы для перенаправления после входа в систему. - Используйте
DelegatingAuthenticationEntryPoint
чтобы либо 403 выполнить запрос напрямую, либо перенаправить на вход в систему в соответствии с сопоставителем.
Смотрите пример здесь:
http://distigme.wordpress.com/2012/11/01/ajax-and-spring-security-form-based-login/
Ответ 4
Он должен вернуть ошибку 403, если вы не настроите ее на другой URL с этим тегом:
<sec:access-denied-handler error-page="/urlToGoIfForbidden" />