Как работать с HTTP 403 с помощью Spring Security 3.0.x - PullRequest
12 голосов
/ 15 ноября 2010

У меня небольшая проблема с Spring Security 3.0.x (в частности, с 3.0.2 на данный момент).Все приложение, над которым я работаю, работает отлично, за исключением случаев, когда кто-то, у кого нет полномочий, пытается войти в систему.

Когда это происходит, пользователи перенаправляются на страницу «приветствия», поскольку его имя пользователя/ пароль действительны, и он получает симпатичную белую страницу с таким сообщением: «Ошибка 403: доступ запрещен»

Итак, я искал в сети, пытаясь найти, как это поведение может быть обработано.Пока я пришел к выводу, пожалуйста, исправьте меня, если я ошибаюсь, что он управляется ExceptionTranslationFilter .Но я не совсем понимаю, как правильно использовать эту информацию.

Я попытался отредактировать свой SecurityContext.xml, чтобы добавить тег access-denied-handler к моему http , но он не работает.Нужно ли добавлять больше, чем этот тег, чтобы он работал?Есть ли другие возможности сделать мое приложение более удобным для пользователей?

Редактировать : я бы хотел перенаправить на страницу, скажем, 403.html, например.

С уважением,
Спасибо

Ответы [ 5 ]

22 голосов
/ 16 ноября 2011

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

 <security:access-denied-handler error-page="/accessDenied"/> - works like charm.

Не забудьте указать обработчик в вашем контроллере:

 @RequestMapping(value = "/accessDenied")
      public String accessDenied() {

            return "accessDenied"; // logical view name
       }

Обновление для Spring Boot (октябрь 2014 г.):

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling().accessDeniedHandler(customHandler) OR .accessDeniedPage("/somePage.html").and
            .formLogin()
                .failureHandler(ajaxAuthenticationFailureHandler)} 

В настоящее время мы на самом деле не возвращаем представления для такой задачи, так как запускается angular js, так что вы можете использовать свой обработчик неудачи / успеха и возвращать адаптированные ответы JSON. Для нас было достаточно использовать обработчик сбоев, но вы можете выбрать, где вы хотите, чтобы ваш элемент управления активировался. Обычно мы не используем средства разрешения представления, поскольку существуют фреймворки тайлов UI (такие как угловые партиалы), способные создавать части на одной странице. для тебя. Части HTML хранятся на сервере и служат просто статическими ресурсами.

Давайте поиграем с Embedded Tomcat, чтобы добиться поведения, аналогичного web.xml!

@Configuration
@EnableAutoConfiguration
public class ApplicationWebXml extends SpringBootServletInitializer {

private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.profiles(addDefaultProfile())
            .showBanner(false)
            .sources(Application.class);
}

//required for container customizer to work, the numerous tutorials didn't work for me, so I simply tried overriding the default one
@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
    return tomcat;
}

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer(

) {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
             containerFactory.setSessionTimeout(1); // just for your interest, remove as necessary

            containerFactory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/views/accessDenied.html"),
                    new ErrorPage(HttpStatus.NOT_FOUND,"/views/notFound.html"));
            containerFactory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
                    connector.setPort(8082);// just for your interest, remove as necessary
                }
            });
        }
    };
}

}

9 голосов
/ 19 ноября 2010

Более чистый способ обработки перенаправлений ошибок - использовать теги <error-page> и <error-code> в вашем web.xml Ниже приведен пример:

<!-- Custom 403 Error Page -->
<!--
            NOTE: Security will throw this error when a user has been authenticated successfully
            but lacks the permissions to perform the requested action.
    -->
    <error-page>
        <error-code>403</error-code>
        <location>/403.jsp</location>
    </error-page>

Этот блок кода будет перенаправлять в указанное место всякий раз, когда он встречает указанный код ошибки.

Это устраняет необходимость в коде авторизации внутри логики вашего приложения.

8 голосов
/ 10 декабря 2010

Я нашел, как это сделать.Реализуя интерфейс AccessDeniedHandler и соответствующий метод обработки, я могу легко контролировать способ обработки ошибки Http 403.

Таким образом, вы можете добавлять различные элементы в сеанс, а затемперехватить их на вашем JSP.

Файл XML выглядит следующим образом:

<sec:http>
    <!-- lots of urls here -->
    <sec:access-denied-handler ref="accessDeniedHandler" />
    <sec:anonymous/>
</sec:http>

<bean id="accessDeniedHandler" class="foo.bar.CustomAccessDeniedHandler">
    <property name="accessDeniedUrl" value="403.html" />
</bean>

Класс Java:

package foo.bar;
public class CustomAccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler {
private String accessDeniedUrl;

    public CustomAccessDeniedHandler() {
    }

    public CustomAccessDeniedHandler(String accessDeniedUrl) {
        this.accessDeniedUrl = accessDeniedUrl;
    }

    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.sendRedirect(accessDeniedUrl);
        request.getSession().setAttribute("CustomSessionAttribute", "value here");
    }

    public String getAccessDeniedUrl() {
        return accessDeniedUrl;
    }

    public void setAccessDeniedUrl(String accessDeniedUrl) {
        this.accessDeniedUrl = accessDeniedUrl;
    }
}

И пример JSP:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <c:if test="${!empty CustomSessionAttribute}">
    <br/>
    ACCESS IS DENIED
    <br/>
 </c:if>
<!-- other stuff down here -->
3 голосов
/ 15 ноября 2010

Способ сделать эту работу - определить обработчик в вашей точке входа:

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {

        if (authException != null) {
            // you can check for the spefic exception here and redirect like this
            response.sendRedirect("403.html");
        }
    }
}

Вы можете определить это как точку входа, установив ее как точку входа в файле конфигурации xml:

<http entry-point-ref="customAuthenticationEntryPoint">

  ...

</http>
1 голос
/ 04 декабря 2010

Вы проверили тег в приложении, и мне кажется, что он работает.

<sec:access-denied-handler error-page="/handle403Url" />

где handle403Url Я хочу вызвать эту ошибку (например, чтобы показать ошибку).

Не забывайте, что вы должны разрешить этот URL-адрес в фильтрах, чтобы он мог быть достигнут этим пользователем, поэтому в начале анализа вы должны добавить что-то вроде этого:

<sec:intercept-url pattern="/handle403Url" filters="none" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...