首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Spring:如何使过滤器抛出自定义异常?

Spring:如何使过滤器抛出自定义异常?
EN

Stack Overflow用户
提问于 2017-05-17 22:58:23
回答 3查看 17.2K关注 0票数 6

我创建了一个过滤器,对JWT令牌的每个请求头进行身份验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class JWTAuthenticationFilter extends GenericFilterBean {

    private UserDetailsService customUserDetailsService;
    private static Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class);
    private final static UrlPathHelper urlPathHelper = new UrlPathHelper();

    public JWTAuthenticationFilter(UserDetailsService customUserDetailsService) {
        this.customUserDetailsService = customUserDetailsService;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request, customUserDetailsService);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        if (authentication == null) {
            logger.debug("failed authentication while attempting to access " + urlPathHelper.getPathWithinApplication((HttpServletRequest) request));
        }
        filterChain.doFilter(request, response);
    }

}

我想抛出一个自定义异常,该异常返回一个响应:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ResponseStatus(value=HttpStatus.SOMECODE, reason="There was an issue with the provided authentacion information")  // 409
public class CustomAuthenticationException extends RuntimeException {

    private static final long serialVersionUID = 6699623945573914987L;

}

我该怎么做?捕捉过滤器抛出的这种异常的最佳设计是什么?Spring安全提供了什么类型的异常处理机制,我可以在一个点内使用和捕获所有的异常处理机制吗?是否有其他方法在筛选器中抛出自定义异常?

备注:还有另一个问题这里,它接受的答案没有回答我的问题。在到达任何控制器之前,我想返回一个响应。

我想要处理的错误情况: 1.客户端为授权头发送一个空值。2.客户端发送格式错误的令牌

在这两种情况下,我都会得到一个使用500 HTTP状态代码的响应。我要拿回4XX代码。

EN

回答 3

Stack Overflow用户

发布于 2017-05-17 23:04:18

看看@ControllerAdvice

下面是我的项目的一个例子。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

    private final Logger log = Logger.getLogger(this.getClass().getSimpleName());

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = RuntimeException.class)
    public Response handleBaseException(RuntimeException e) {
        log.error("Error", e);
        Error error = new Error(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.name());
        return Response.status(HttpStatus.BAD_REQUEST.value()).error(error, null).build();
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Response handleNoHandlerFoundException(Exception e) {
        log.error("Error", e);
        Error error = new Error(HttpStatus.NOT_FOUND.value(), HttpStatus.NOT_FOUND.name());
        return Response.status(HttpStatus.NOT_FOUND.value()).error(error, null).build();
    }

    @ExceptionHandler(value = AuthenticationCredentialsNotFoundException.class)
    public Response handleException(AuthenticationCredentialsNotFoundException e) {     
        log.error("Error", e);
        Error error = new Error(ErrorCodes.INVALID_CREDENTIALS_CODE, ErrorCodes.INVALID_CREDENTIALS_MSG);
        return Response.status(ErrorCodes.INVALID_CREDENTIALS_CODE).error(error, null).build();
    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(value = UnauthorisedException.class)
    public Response handleNotAuthorizedExceptionException(UnauthorisedException e) {        
//      log.error("Error", e);
        return Response.unauthorized().build();
    }

    @ExceptionHandler(value = Exception.class)
    public String handleException(Exception e) {
        log.error("Error", e);
        return e.getClass().getName() + " 14" + e.getMessage();
    }


}

编辑

我相信你可以在response.sendError里面做过滤方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request, customUserDetailsService);
    SecurityContextHolder.getContext().setAuthentication(authentication);
    if (authentication == null) {
        logger.debug("failed authentication while attempting to access " + urlPathHelper.getPathWithinApplication((HttpServletRequest) request));
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid authentication.");
        setUnauthorizedResponse(response);
        return;
    }
    filterChain.doFilter(request, response);
}

public void setUnauthorizedResponse(HttpServletResponse response) {
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    response.setContentType("application/json");
    Response unAuthorizedResponse = Response.unauthorized().build();
    try {
        PrintWriter out = response.getWriter();
        out.println(unAuthorizedResponse.toJsonString());
    } catch (IOException e) {
        log.error("Error", e);
    }
}
票数 4
EN

Stack Overflow用户

发布于 2017-09-21 12:59:03

我对JWT令牌也有同样的问题,并在这个问题上发布了解决方案,因为这个问题类似(他在过滤器异常方面有问题)。

票数 0
EN

Stack Overflow用户

发布于 2021-07-06 22:29:54

免责声明:这不是问题的答案,但这是对Arian提出的问题的后续回答。

如上文所述,在春季容器允许我们访问bean之前,您可以在这些地方进行自动测试。

在这里,我正在自动完成我的BlacklistJwtRepo

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (blacklistJwtRepo == null) { //Lazy Load because filter
        ServletContext servletContext = req.getServletContext();
        WebApplicationContext webApplicationContext =  WebApplicationContextUtils.getWebApplicationContext(servletContext);
        blacklistJwtRepo = webApplicationContext.getBean(BlacklistJwtRepo.class);
    }

我在这里找到了req对象-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;

最后的代码看起来-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;      
    System.out.println("blacklistJwtRepo : " + blacklistJwtRepo);
    //till here the autowired repo (blacklistJwtRepo) is null
    if (blacklistJwtRepo == null) { //Lazy Load because filter
        ServletContext servletContext = req.getServletContext();
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        blacklistJwtRepo = webApplicationContext.getBean(BlacklistJwtRepo.class);
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44040703

复制
相关文章
C#中的属性
属性在C#中很常用,但有部分开发人员对它既熟悉又陌生。概念上属性是将元数据关联到元素的方式。属性的使用方法我们在代码中经常肩见到,比如下面这样的:
喵叔
2021/12/22
1.8K0
WPF 关于将 ManipulationDeltaEventArgs 的 Manipulators 属性返回值修改为 ReadOnlyCollection 类型的提议
讨论的地方是: How about change the type of ManipulationDeltaEventArgs.Manipulators property to ReadOnlyCollection · Discussion #6249 · dotnet/wpf
林德熙
2022/03/28
1.1K0
C# 附加属性
附加属性我们早就使用过,常见的用于控件定位的Grid.Row,Grid.Column就是附加属性,那这个东西具体是什么意思呢?请设想这样的情景:一个学生,他在社团可以是社长,他在班内可以是班长,在赛场又可以是运动员,这些特定的属性,并不是每个学生都具有的,只有学生参与了或者在某个环境中,才具有这样的属性。那我们在定义学生类时,就不能把这些属性定义进去,为了解决这种在某些环境中才具有特定属性的情况,WPF引入了附加属性,附加属性就是一个对象可以被它外部的环境附加某些属性,而对象本身实际上不具有这样的属性。
zls365
2021/09/02
1.2K0
C# 附加属性
C#的Button.DialogResult属性[通俗易懂]
如果此属性的DialogResult不是设置为None,并且父窗体是通过ShowDialog方法显示的,则不必挂钩任何事件,单击按钮也可关闭父窗体。然后,该窗体的DialogResult属性将设置为该按钮被单击时的DialogResult。
全栈程序员站长
2022/06/25
9700
Objective-C中的属性机制
        Objective-C 2.0中的属性机制为我们提供了便捷的获取和设置实例变量的方式,也可以说属性为我们提供了一个默认的设置器和访问器的实现。在学习OC中属性之前我们先要知道为什么要为变量实现getter和setter方法,我们先来了解一下实例的作用域。     实例变量的作用域如下:         1. @public : 共有的,该实例变量谁都可以访问;         2.@protected :受保护的,该实例变量只能在该类和其子类内访问,父类protected的实例变量在子类中
lizelu
2018/01/12
1.3K0
C#中Dock属性的作用[通俗易懂]
当在C#项目开发中,在窗体界面的设置经常用到Dock属性值。这里一panel面板的Dock属性值为例描述其作用。
全栈程序员站长
2022/10/01
1.2K0
C#中Dock属性的作用[通俗易懂]
Word 技术篇-段落的前后间距单位磅改为行,行改为磅
很多时候,比如我们写论文,word的格式是有严格要求的,我们要一丝不苟的按照要求来。因为,这是一种规范,也是是一种礼仪。
小蓝枣
2020/09/23
1.8K0
Objective-C属性(property)的特性(attribute)
以下:「attribute(s)」,「特性」是指同一事物(都指@property后面括号内的单词)。
iOS Development
2019/02/14
2K0
Word文档段落的前后间距单位磅改为行,行改为磅方法演示
很多时候,比如我们写论文,word 的格式是有严格要求的,我们要一丝不苟的按照要求来。因为,这是一种规范,也是是一种礼仪。
小蓝枣
2023/05/27
1.8K0
Word文档段落的前后间距单位磅改为行,行改为磅方法演示
C#中的方括号[](特性、属性)
首先要说的是,可能一些刚接触C#的朋友常常容易把属性(Property)跟特性(Attribute)弄混淆,其实这是两种不同的东西。属性就是面向对象思想里所说的封装在类里面的数据字段,其形式为:
vv彭
2020/12/28
7.8K0
C#中的方括号[](特性、属性)
C#中的类、方法和属性
这节讲C#中的类,方法,属性。这是面向对象编程中,我们最直接打交道的三个结构。
宿春磊Charles
2022/03/29
2K0
C#中的类、方法和属性
Mac复制改为拷贝
在默认情况下,mac电脑的复制为复制+粘贴,即会生成一个副本文件,并没有达到Win下复制功效。
努力在北京混出人样
2021/09/10
7460
C++17常用新特性(七)---新的属性和属性特性
C++17 增加了一些新的属性,这些属性并不是强制使用,但是正确使用后确实能够帮助我们避免一些问题,而这些问题恰恰是在做项目的时候容易忽略的,比较常见的一类问题是在前面把变量全部进行了定义,但是后面没有使用,还有一种是对于函数的返回值没有进行判断等,在本文中,将主要对C++17新增的一些属性进行解释和说明。
CPP开发前沿
2022/04/13
1.5K0
C++17常用新特性(七)---新的属性和属性特性
C#设置有命令空间的属性
之前被问到一个问题,C#中如何设置android:name这样的属性?我的第一反应是直接setAttribute不就可以了么 SetAttribute(name, value), 可事实上却不行,因为本身并没有什么C#的开发经验,周围也没什么人搞这个,所以就只能通过搜索了。
meteoric
2018/11/19
6960
[读书笔记]C#学习笔记五: C#3.0自动属性,匿名属性及扩展方法
前言 这一章算是看这本书最大的收获了, Lambda表达式让人用着屡试不爽, C#3.0可谓颠覆了我们的代码编写风格. 因为Lambda所需篇幅挺大, 所以先总结C#3.0智能编译器给我们带来的诸多好处, 下一遍会单独介绍Lambda表达式. 这篇主要包括的内容有: 自动属性,隐式类型,对象集合初始化,匿名类型,扩展方法. 下面一起来看下C#3.0 所带来的变化吧. 1,自动实现的属性 在C#3.0之前, 定义属性时一般会像下面这样去编写代码: 1 class Person 2 { 3 /
一枝花算不算浪漫
2018/05/18
8270
C# winform DataGridView 常见属性
C# winform DataGridView 属性说明 ① 取得或者修改当前单元格的内容 ② 设定单元格只读 ③ 不显示最下面的新行 ④ 判断新增行 ⑤ 行的用户删除操作的自定义 ⑥ 行、列的隐藏和删除 ⑦ 禁止列或者行的Resize ⑧ 列宽和行高以及列头的高度和行头的宽度的自动调整 ⑨ 冻结列或行 ⑩ 列顺序的调整 ⑪ 行头列头的单元格 ⑫ 剪切板的操作 ⑬ 单元格的ToolTip的设置 ⑭ 右键菜单(ContextMenuStrip)的设置 ⑮ 单元格的边框、 网格线样式的设定 ⑯ 单元格表示值的设定 ⑰ 用户输入时,单元格输入值的设定 ⑱ 设定新加行的默认值
全栈程序员站长
2022/09/07
3.9K0
C# 可空引用类型 Nullable 更强制的约束:将警告改为错误 WarningsAsErrors
于是 C# 8.0 带来的可空引用类型由于默认以警告的形式出现,所以实际上约束力非常弱。
walterlv
2023/10/22
4040
C# 可空引用类型 Nullable 更强制的约束:将警告改为错误 WarningsAsErrors
C++0x 通用属性
C++在不断的发展,但每一阶段的C++标准提供的功能都很难完全满足现实需求,于是为了弥补标准的不足或者扩增特性应用场景所需的特性,各大C++编译器厂商多多少少在标准之外都增加了不少有用的扩展功能。这些扩展功能并不在C++的标准中,但是却经常被使用。有时候,C++标准委员会也会考虑这些标准之外的扩增特性,将其纳入标准之中。
恋喵大鲤鱼
2018/09/27
9140
C# devExpress BandedGridView属性 备忘
BandedGridView属性备忘 StringBuilder sb = new StringBuilder(); DevExpress.XtraGrid.Views.BandedGrid.BandedGridView view = bandedGridView1 as DevExpress.XtraGrid.Views.BandedGrid.BandedGridView; List<GridBand> gridBand = new List<GridBan
乔达摩@嘿
2020/09/11
1.3K0
Android系统属性(c接口)
属性是在整个系统中全局可见的。每个进程可以get/set属性。在编译的过程中会将各种系统参数汇总到build.proc 以及default.proc 这两个文件中,主要属性集中在build.proc中。
李小白是一只喵
2020/04/24
9500
Android系统属性(c接口)

相似问题

Wix ProgramFiles64Folder仍然

40

ConnectionString属性尚未初始化。怎么修呢?

22

将属性更改为最终属性

11

Eclipse -属性改为大写

10

WPF / C#将ObservableCollection中的项的属性更改为ListBox

36
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文