Spring security 全局异常处理程序没有捕获任何异常

问题描述 投票:0回答:0

在我的网络安全配置中,我明确设置了一个访问被拒绝的处理程序,如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http
            .addFilterBefore(devProfileFilter, UsernamePasswordAuthenticationFilter.class)
            .addFilterAfter(customAuthenticationFilter, DevProfileFilter.class)
            .authorizeRequests()
            .antMatchers("/users/**").hasAuthority("ROLE_ADMIN")
            .antMatchers("/upload/**").hasAuthority("ROLE_SUBMITTER")
            .antMatchers("/download/**").hasAuthority("ROLE_REQUESTER")
            .antMatchers("/api/**", "/swagger-ui.html").hasAuthority("ROLE_APIACCESS")
            .anyRequest()
            .authenticated() // All requests need authentication through RP
            .and()
            .headers()
            .frameOptions()
            .deny()
            .and()
            .csrf() // Enable CSRF protection (enabled by default)
            .and()
            .exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) ->
            {
                // Set response status
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                // Throw the exception to be caught by the GlobalExceptionHandler
                throw accessDeniedException;
            });

然后我像这样定义了一个全局异常处理程序类:

@ControllerAdvice
public class GlobalExceptionHandler
{
    @Autowired
    private ForbiddenAccessRepository forbiddenAccessRepository;

    @ExceptionHandler(AccessDeniedException.class)
    public ModelAndView handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request, Model model) {
        int status = HttpStatus.FORBIDDEN.value();
        model.addAttribute("status", status);
        model.addAttribute("exception", ex.getMessage());

        // Log forbidden access
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null && auth.getPrincipal() instanceof User) {
            User            user            = (User) auth.getPrincipal();
            ForbiddenAccess forbiddenAccess = new ForbiddenAccess();
            forbiddenAccess.setBemsid(user.getBemsid());
            forbiddenAccess.setPage(request.getRequestURI());
            forbiddenAccess.setAccessTime(LocalDateTime.now());
            ForbiddenAccess saved = forbiddenAccessRepository.save(forbiddenAccess);
            System.out.println("Saved ForbiddenAccess: " + saved);
        }

        System.out.println("Access Denied Exception Handled: Status = " + status);

        return new ModelAndView("error");
    }

    // TODO: Replace with specifically handled exceptions.
    // Catch-all for any other exceptions not handled above
    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception ex, Model model) {
        model.addAttribute("status", HttpStatus.INTERNAL_SERVER_ERROR);
        model.addAttribute("exception", ex.getMessage());
        return new ModelAndView("error");
    }
}

我预计,如果我试图在没有适当角色的情况下访问 Web 应用程序的一部分,我的安全配置会抛出 403 错误,并由我的全局异常处理程序接收。

但是我没有在全局异常处理程序中触发任何断点或打印语句。相反,相应的错误页面 (error.html) 正在显示,但显示 500 错误并且我没有插入到我的禁止访问存储库中。

编辑:我更新了我的 Spring Security 配置中的 .exceptionHandling() 方法,现在 999 渗透到顶部,但仍然没有断点触发或来自全局异常处理程序的数据库插入。

                .and()
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler()
                {
                    @Override
                    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException
                    {
                        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                        if (auth != null && auth.getPrincipal() instanceof User)
                        {
                            User            user            = (User) auth.getPrincipal();
                            ForbiddenAccess forbiddenAccess = new ForbiddenAccess();
                            forbiddenAccess.setBemsid(user.getBemsid());
                            forbiddenAccess.setPage(request.getRequestURI());
                            forbiddenAccess.setAccessTime(LocalDateTime.now());
                            forbiddenAccessRepository.save(forbiddenAccess);
                        }
                        // Set response status
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        // add status to the request
                        request.setAttribute("status", HttpServletResponse.SC_FORBIDDEN);
                        // forward to error page
                        request.getRequestDispatcher("/error").forward(request, response);
                    }
                });
java spring-boot spring-security
© www.soinside.com 2019 - 2024. All rights reserved.