«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.baeldung.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.