У меня маленький веб-приложение на основе Spring MVC и Spring Security. У меня возникли трудности с настройкой собственного AccessDeniedHandler, который должен перенаправлять неавторизованных пользователей на мою пользовательскую страницу ошибок.
Я использую http.exceptionHandling().accessDeniedHandler(accessDeniedHandler) в своем классе конфигурации, который расширяет WebSecurityConfigurerAdapter. Значение по умолчанию AccessDeniedHandler продолжает вызываться, несмотря на настройку (я отладил ExceptionTranslationFilter). В результате вместо моей пользовательской страницы отображается определенная контейнером страница ошибки.
У вас есть идея, что мне здесь не хватает? В чем может быть проблема? Большое спасибо за вашу помощь.
Выдержка из моего Суперкласс WebSecurityConfigurerAdapter:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/static/**", "/login/*", "/login").permitAll()
.antMatchers("/site/admin*").hasRole("ADMIN")
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/login")
.usernameParameter("user-name")
.passwordParameter("password")
.defaultSuccessUrl("/site/welcome", true)
.loginProcessingUrl("/process-login")
.failureUrl("/login?login_error=1")
.and().logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.and().sessionManagement()
.invalidSessionUrl("/login")
.and().csrf()
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}
Моя собственная реализация AccessDeniedHandler:
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
private static Logger LOG = Logger.getLogger(CustomAccessDeniedHandler.class);
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
LOG.warn(String.format("User [%s] attempted to access the protected URL [%s]!", authentication.getName(), request.getRequestURI()));
}
response.sendRedirect(request.getContextPath() + "/site/403");
}
}
@StanislavL Вот оно! Я понятия не имею, почему он не вводит bean-компонент в класс конфигурации. Другие классы в том же пакете внедряются без проблем. Я пытался назвать компонент и внедрить его с помощью @Qualifier, но безрезультатно... Я попытаюсь создать компонент вручную, используя аннотацию @Bean, но я не вижу причин, по которым он не работает так, как сейчас. ... :(




Я забыл присвоить параметр автосвязывания конструктора полю! Прошу прощения, что разместил здесь такую тривиальную проблему, но после того, как я потратил полдня на поиск решения, я был слеп и пропустил это...
public SpringSecurityConfiguration(
AccessDeniedHandler accessDeniedHandler, ...) {
this.accessDeniedHandler = accessDeniedHandler; // This line was missing.
...
}
Попробуйте проверить, создается ли экземпляр CustomAccessDeniedHandler вообще. Может быть проблема с распознаванием боба, например. bean вне пути сканирования.