当前位置: 首页 > 面试题库 >

使用@ExceptionHandler处理Spring Security身份验证异常

申屠宗清
2023-03-14
问题内容

我正在使用Spring MVC @ControllerAdvice@ExceptionHandler处理REST Api的所有异常。对于Web MVC控制器抛出的异常,它工作正常,但对于Spring Security自定义过滤器抛出的异常,它不工作,因为它们在调用控制器方法之前运行。

我有一个自定义的spring安全过滤器,它执行基于令牌的身份验证:

public class AegisAuthenticationFilter extends GenericFilterBean {

...

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        try {

            ...         
        } catch(AuthenticationException authenticationException) {

            SecurityContextHolder.clearContext();
            authenticationEntryPoint.commence(request, response, authenticationException);

        }

    }

}

使用此自定义入口点:

@Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{

    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
    }

}

并使用此类来全局处理异常:

@ControllerAdvice
public class RestEntityResponseExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler({ InvalidTokenException.class, AuthenticationException.class })
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    @ResponseBody
    public RestError handleAuthenticationException(Exception ex) {

        int errorCode = AegisErrorCode.GenericAuthenticationError;
        if(ex instanceof AegisException) {
            errorCode = ((AegisException)ex).getCode();
        }

        RestError re = new RestError(
            HttpStatus.UNAUTHORIZED,
            errorCode, 
            "...",
            ex.getMessage());

        return re;
    }
}

我需要做的是返回一个详细的JSON主体,即使对于spring security AuthenticationException也是如此。有没有办法使Spring Security AuthenticationEntryPoint和Spring MVC @ExceptionHandler一起工作?

我正在使用Spring Security 3.1.4和Spring MVC 3.2.4。


问题答案:

我尝试按照建议从AuthenticationEntryPoint自己编写json,它可以工作。

仅出于测试目的,我通过删除response.sendError更改了AutenticationEntryPoint

@Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{

    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {

        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getOutputStream().println("{ \"error\": \"" + authenticationException.getMessage() + "\" }");

    }
}

这样,即使您使用的是Spring Security AuthenticationEntryPoint,也可以将自定义json数据与未经授权的401一起发送。

显然,您不会像我出于测试目的那样构建json,但会序列化一些类实例。



 类似资料:
  • 我使用Spring MVC的和来处理REST API的所有异常。它对web mvc控制器引发的异常很好,但对spring security自定义筛选器引发的异常不起作用,因为它们在调用控制器方法之前运行。 我有一个自定义Spring Security筛选器,它执行基于令牌的身份验证: 使用此自定义入口点:

  • 问题内容: C#中基于Selenium Webdriver的测试必须使用Windows身份验证登录。 我尝试了几种方法: 和 都不成功。我没有在本地系统上获得Windows身份验证对话框,因此无法查看源来确定如何使用Selenium By方法定位用户名和密码。 我相信Windows身份验证对话框是由浏览器提供的,但是我没有找到该对话框的任何来源。 使用Selenium(不是AutoIt或其他类似工

  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe

  • 问题内容: 有谁知道在自动化过程中使用Selenium或任何其他工具来处理浏览器身份验证吗? 问题答案: 警报方法authenticateUsing() 使您可以跳过“ Http基本身份验证”框。 从Selenium 3.4开始,它仍处于测试阶段 现在,仅针对 InternetExplorerDriver

  • 问题内容: 尝试进行某些路由需要身份验证。 我有这个: 注意:是的,身份验证服务可以正常工作。 对于每条路由,我都会检查用户是否已通过身份验证,如果没有通过身份验证,则要将他们重定向到登录页面,如果已通过身份验证,则它将以“ /”路由登陆到第一页。 我得到的是: 我在哪里做错了? 问题答案: 一个简单的解决方案是制作一个包含所有受保护路线的(高阶组件)。 根据您的应用程序的嵌套方式,您可能需要利用

  • 问题内容: 下面是我的AutoIt脚本(UI3_Authentication.au3),用于处理Windows身份验证弹出窗口。 以下是我对上述AutoIt exe文件的Selenium代码调用。 当我运行上述Selenium文件时,它将打开页面并弹出身份验证。但这不是在插入用户名和密码。它等待用户输入。 问题答案: 我解决了 其实这是我的坏事。以前,我的代码是这样的: 我在get()之前添加了a