如何修复 Spring 安全 (Java) 配置中默认 AccessDeniedHandler (AccessDeniedHandlerImpl) 的覆盖?

How to fix overriding of default AccessDeniedHandler (AccessDeniedHandlerImpl) in Spring Security (Java) config?

我有一个基于 Spring MVC 和 Spring 安全性 的小型 Web 应用程序。我很难设置我自己的 AccessDeniedHandler 应该将未经授权的用户重定向到我的自定义错误页面。

我在扩展 WebSecurityConfigurerAdapter 的配置 class 中使用 http.exceptionHandling().accessDeniedHandler(accessDeniedHandler)。尽管进行了设置(我调试了 ExceptionTranslationFilter),但仍会调用默认 AccessDeniedHandler。结果显示的是容器定义的错误页面,而不是我自定义的错误页面。

你知道我在这里遗漏了什么吗?可能是什么问题?非常感谢您的帮助。

摘自我的 WebSecurityConfigurerAdapter super class

@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");
    }
}

我忘了将自动装配的构造函数参数分配给一个字段!很抱歉在这里发这么一个小问题,但是我花了半天的时间寻找解决方案,我瞎了,我错过了...

public SpringSecurityConfiguration(
            AccessDeniedHandler accessDeniedHandler, ...) {
        this.accessDeniedHandler = accessDeniedHandler; // This line was missing.
        ...
}