spring 无法调用我的自定义AccessDeniedHandler

piah890a  于 2023-03-16  发布在  Spring
关注(0)|答案(1)|浏览(170)

在我的Sping Boot 应用程序中,我实现了一个自定义AccessDeniedHandler,但它从未调用过,而是用自定义authenticationEntryPoint代替了它

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;
    
    @Autowired
    private YzlAccessDeniedHandler yzlAccessDeniedHandler;
    
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        httpSecurity
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers("/yzl/**").access("@yzlAccessImpl.hasPermit(request)")
                .antMatchers(
                        HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js"
                ).permitAll()
                .anyRequest().authenticated()
                .and()
                .headers().frameOptions().disable();
        httpSecurity.exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .accessDeniedHandler(yzlAccessDeniedHandler);
    }
}

自定义拒绝访问处理程序

@Component
public class YzlAccessDeniedHandler implements AccessDeniedHandler, Serializable
{
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setStatus(403);
response.getWriter().write("Forbidden: access error" + accessDeniedException.getMessage());
}
}

自定义身份验证入口点实现

@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
{
private static final long serialVersionUID = -8970718410437077606L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
            throws IOException
    {
        response.setStatus(401);
        response.getWriter().write("Forbidden: Authentication failed");
    }

}

我让accessImpl中的自定义方法总是返回false,并且我期望响应是“Forbidden”:访问错误”,而它是“禁止:验证失败””。

@Component 
public class YzlAccessImpl implements YzlAccess 
{     
 @Override     
 public boolean hasPermit(HttpServletRequest request) {         
 return false;     
 } 
}
polhcujo

polhcujo1#

这是Spring Security处理自身异常方式的一个不幸的局限性,你可以在Spring Security的bug报告(已被拒绝)中读到更多关于它的信息:https://github.com/spring-projects/spring-security/issues/6908#issuecomment-533269673
在这种情况下,唯一要做的事情就是在ExceptionHandler中发现与SpringSecurity相关的异常,并重新抛出它们。
enter image description here

相关问题