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 .