Spring Security - настройте страницу 403 Запрещено / Доступ запрещен
1. Вступление
В этой статье мы покажем, какcustomize the access denied page in a Spring Security project.
Этого можно добиться либо с помощью конфигурации Spring Security, либо с помощью конфигурации веб-приложения в файлеweb.xml.
В остальных разделах мы более подробно рассмотрим каждый из этих вариантов.
2. Пользовательский JSP
Каждый раз, когда пользователь пытается получить доступ к странице, которая ограничена ролями, которых у него нет, приложение возвращает код состояния 403, что означаетAccess Denied.
Чтобы заменить страницу ответа состояния Spring 403 на настраиваемую,let’s first create a JSP file called accessDenied.jsp:
3. Конфигурация Spring Security
По умолчанию в Spring Security определенExceptionTranslationFilter, который обрабатывает исключения типаAuthenticationException иAccessDeniedException. Последнее осуществляется с помощью свойстваaccessDeniedHandler,, которое использует классAccessDeniedHandlerImpl.
Чтобы настроить это поведение для использования нашей собственной страницы, которую мы создали выше, нам нужно переопределить свойства классаExceptionTranslationFilter. Это можно сделать с помощью конфигурации Java или конфигурации XML.
3.1. Доступ запрещен к странице
Используя Java,we can customize the 403 error handling process by using the accessDeniedPage() or accessDeniedHandler() methods при настройке элементаHttpSecurity.
Давайте создадим конфигурацию аутентификации, которая ограничивает URL-адреса“/admin/** рольюADMIN и устанавливает страницу отказа в доступе на нашу пользовательскую страницуaccessDenied.jsp:
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
// ...
.and()
.exceptionHandling().accessDeniedPage("/accessDenied.jsp");
}
Давайте посмотрим на эквивалентную конфигурацию XML для страницы с отказом в доступе:
3.2. Обработчик отказа в доступе
Использование обработчика отказа в доступе вместо страницы имеет то преимущество, что мы можем определить пользовательскую логику, которая будет выполняться перед перенаправлением на страницу 403. Для этогоwe need to create a class that implements the AccessDeniedHandler interface и отменяет метод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");
}
}
В конфигурации безопасностиwe’ll define the bean and set the custom AccessDeniedHandler:
@Bean
public AccessDeniedHandler accessDeniedHandler(){
return new CustomAccessDeniedHandler();
}
//...
.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
Если мы хотим настроить классCustomAccessDeniedHandler, определенный выше, с использованием XML, конфигурация будет выглядеть немного иначе:
4. Конфигурация приложения
Handling the access denied error can be done through the web.xml file of a web application, by defining an error-page tag. Он содержит два вложенных тега, называемыхerror-code,, которые определяют код состояния, который должен быть перехвачен, иlocation,, обозначающий URL-адрес, на который пользователь будет перенаправлен в случае обнаружения кода ошибки:
403
/accessDenied
Если в приложении нет файлаweb.xml, как в случае с Spring Boot, аннотации Spring в настоящее время не предоставляют точной альтернативы тегуerror-page. Согласно документации Spring, в этом случае рекомендуется использовать методыaccessDeniedPage() иaccessDeniedHandler(), представленные в разделе 3.
5. Заключение
В этой быстрой статье мы подробно описали различные способы обработки ошибки «отказ в доступе» с помощью пользовательской страницы 403.
Полный исходный код статьи можно найти в папкеGitHub project.