Ошибка безопасности Spring при попытке перенаправления Доступ запрещен

Реализовал реализацию весенней безопасности в моем проекте, но у меня возникли проблемы с определением перенаправления. Когда доступ заблокирован, мне нужно перенаправить этого пользователя на определенный URL-адрес.

Когда я помещаю тег «обработчик отказа в доступе», я надеюсь, что он перенаправляет на страницу, определенную в компоненте, но этого не происходит.

безопасность-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans.xsd
                       http://www.springframework.org/schema/security
                       http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<!-- Method Security -->
<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler" />
</security:global-method-security>


<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>

<bean id="permissionEvaluator" class="net.pontoall.hemisphere.security.HemispherePermissionEvaluator"/>

<!-- Publicos -->
<security:http pattern="/layouts/**" security="none" />
<security:http pattern="/messages/**" security="none" />
<security:http pattern="/test/**" security="none" />
<security:http pattern="/resources/**" security="none" />
<security:http pattern="/login/**" security="none" />
<security:http pattern="/install/**" security="none" />
<security:http pattern="/cobredireto/**" security="none" />
<security:http pattern="/hotsite/**" security="none" />
<security:http pattern="/captcha.jpg" security="none" />

<security:http auto-config="true" use-expressions="true">

    <security:access-denied-handler ref="HemisphereAccessDeniedHandler"/>

    <security:intercept-url pattern="/**" access="isAuthenticated()" />

    <security:form-login login-page="/login" default-target-url="/home" 
                         authentication-failure-url="/login?logout=true" 
                         authentication-success-handler-ref="authenticationSuccessHandler"
                         authentication-failure-handler-ref="authenticationFailureHandler"/>

    <security:logout logout-url="/j_spring_security_logout" invalidate-session="true" success-handler-ref="logoutHandler"/>
</security:http>

<!-- Authentication Manager -->
<security:authentication-manager alias="authenticationManager">
    <!-- Custom Authentication provider -->
    <security:authentication-provider ref="hemisphereAuthenticationProvider"/>
</security:authentication-manager>

<bean id="hemisphereAuthenticationProvider" class="net.pontoall.hemisphere.security.HemisphereAuthenticationProvider">
    <property name="userDetailsService" ref="userDetailService"/>
</bean>

<bean id="authenticationSuccessHandler" class="net.pontoall.hemisphere.security.HemisphereAuthenticationSuccessHandler">
    <property name="defaultTargetUrl" value="/home" />
    <property name="alwaysUseDefaultTargetUrl" value="no" />
</bean>

<bean id="authenticationFailureHandler" class="net.pontoall.hemisphere.security.HemisphereAuthenticationFailureHandler">
    <property name="defaultFailureUrl" value="/login" />
</bean>

<bean id="logoutHandler" class="net.pontoall.hemisphere.security.HemisphereLogoutHandler"/>

<bean id="HemisphereAccessDeniedHandler" class="net.pontoall.hemisphere.security.HemisphereAccessDeniedHandler">
    <property name="errorPage" value="/error/permissao"/>
</bean>

Bean Java - HemisphereAccessDeniedHandler.java:

public class HemisphereAccessDeniedHandler implements AccessDeniedHandler {

private String errorPage;

public String getErrorPage() {
    return errorPage;
}

public void setErrorPage(String errorPage) {

    if (errorPage == "") {
        errorPage = "/";
    }

    this.errorPage = errorPage;
}

@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
    // Set the 403 status code.
    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
    response.sendRedirect(errorPage);
}

}

person Tiarê Balbi    schedule 31.10.2012    source источник


Ответы (2)


Я обнаружил, что происходит. У меня есть Spring MVC @ExceptionHandler, и он фиксирует ошибку.

@ExceptionHandler
public ResponseEntity<String> handle(Exception exception, HttpServletRequest requestMain) {
    String erro = exception.getMessage();
    PusherRequest request = new PusherRequest("hemisphere-web", requestMain.getSession().getId());
    request.triggerPush(erro);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

    return new ResponseEntity<String>(exception.getMessage(), headers, HttpStatus.FORBIDDEN);
}
person Tiarê Balbi    schedule 31.10.2012
comment
Хорошо, рассмотрите возможность использования атрибута error-page access-denied-handler, если вам все равно нужна простая переадресация, например. `‹отказ в доступе-обработчике error-page=/access-denied.html /›. (static.springsource.org/spring-security/site/docs/3.1.x/) Удачи! - person David Riccitelli; 31.10.2012
comment
Да, я сделал это в первом тесте, но это не сработало, тогда я пошел другим путем :) Спасибо! - person Tiarê Balbi; 31.10.2012

Перенаправление имеет собственный код состояния HTTP (3xx), см. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html. Метод response.sendRedirect должен автоматически устанавливать для кода состояния HTTP значение 307 (временное перенаправление, см. http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletResponse.html#sendRedirect).

Но вы устанавливаете код состояния HTTP на Запрещено (403) перед перенаправлением.

Поэтому попробуйте удалить файл response.setStatus(HttpServletResponse.SC_FORBIDDEN). Вы также можете опубликовать дамп curl, чтобы увидеть необработанный вывод сервера.

person David Riccitelli    schedule 31.10.2012
comment
Я пытался, но не сработало, я отлаживаю его, не входя в класс. - person Tiarê Balbi; 31.10.2012