Перейти к основному содержимому

Spring Security — настройка страницы 403 Forbidden/Access Denied

· 3 мин. чтения

1. Введение

В этой статье мы покажем, как настроить страницу отказа в доступе в проекте Spring Security .

Этого можно добиться либо с помощью конфигурации Spring Security, либо с помощью конфигурации веб-приложения в файле web.xml .

В остальных разделах мы более подробно рассмотрим каждый из этих вариантов.

2. Пользовательский JSP

Всякий раз, когда пользователь пытается получить доступ к странице, которая ограничена ролями, которых у него нет, приложение возвращает код состояния 403, что означает отказ в доступе .

Чтобы заменить страницу ответа о статусе Spring 403 пользовательской, давайте сначала создадим файл JSP с именем accessDenied.jsp :

<body>
<h2>Sorry, you do not have permission to view this page.</h2>

Click <a href="<c:url value="/homepage.html" /> ">here</a>
to go back to the Homepage.
</body>

3. Конфигурация безопасности Spring

По умолчанию Spring Security имеет определенный ExceptionTranslationFilter , который обрабатывает исключения типа AuthenticationException и AccessDeniedException . Последнее выполняется с помощью свойства с именем accessDeniedHandler, которое использует класс AccessDeniedHandlerImpl .

Чтобы настроить это поведение для использования нашей собственной страницы, которую мы создали выше, нам нужно переопределить свойства класса ExceptionTranslationFilter . Это можно сделать с помощью конфигурации Java или конфигурации XML.

3.1. Доступ запрещен к странице

Используя Java, мы можем настроить процесс обработки ошибок 403, используя методы accessDeniedPage() или accessDeniedHandler() при настройке элемента HttpSecurity .

Давайте создадим конфигурацию аутентификации, которая ограничивает URL-адреса «/admin/** » ролью ADMIN и устанавливает страницу отказа в доступе на нашу пользовательскую страницу accessDenied.jsp :

@Override
protected void configure(final HttpSecurity http) throws Exception {
http
// ...
.and()
.exceptionHandling().accessDeniedPage("/accessDenied.jsp");
}

Давайте взглянем на эквивалентную XML-конфигурацию для страницы с отказом в доступе:

<http use-expressions="true">
<access-denied-handler error-page="/accessDenied"/>
</http>

3.2. Обработчик отказа в доступе

Использование обработчика отказа в доступе вместо страницы имеет то преимущество, что мы можем определить пользовательскую логику, которая будет выполняться перед перенаправлением на страницу 403. Для этого нам нужно создать класс, реализующий интерфейс AccessDeniedHandler и переопределяющий метод handle() .

Давайте создадим собственный класс AccessDeniedHandler , который регистрирует предупреждающее сообщение для каждой попытки отказа в доступе, содержащее пользователя, предпринявшего попытку, и защищенный URL-адрес, к которому он пытался получить доступ:

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

public static final Logger LOG
= Logger.getLogger(CustomAccessDeniedHandler.class);

@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException exc) throws IOException, ServletException {

Authentication auth
= SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
LOG.warn("User: " + auth.getName()
+ " attempted to access the protected URL: "
+ request.getRequestURI());
}

response.sendRedirect(request.getContextPath() + "/accessDenied");
}
}

В конфигурации безопасности мы определим bean-компонент и установим пользовательский AccessDeniedHandler :

@Bean
public AccessDeniedHandler accessDeniedHandler(){
return new CustomAccessDeniedHandler();
}

//...
.exceptionHandling().accessDeniedHandler(accessDeniedHandler());

Если мы хотим настроить класс CustomAccessDeniedHandler , определенный выше, с помощью XML, конфигурация будет выглядеть немного иначе:

<bean name="customAccessDeniedHandler" 
class="com.foreach.security.CustomAccessDeniedHandler" />

<http use-expressions="true">
<access-denied-handler ref="customAccessDeniedHandler"/>
</http>

4. Конфигурация приложения

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

<error-page>
<error-code>403</error-code>
<location>/accessDenied</location>
</error-page>

Если у приложения нет файла web.xml , как в случае с Spring Boot, аннотации Spring в настоящее время не предоставляют точной альтернативы тегу error-page . Согласно документации Spring, в этом случае рекомендуется использовать методы accessDeniedPage() и accessDeniedHandler(), представленные в разделе 3.

5. Вывод

В этой быстрой статье мы подробно описали различные способы обработки ошибки отказа в доступе с помощью пользовательской страницы 403.

Полный исходный код статьи можно найти в проекте GitHub .