且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何让Spring-Security以401格式返回401响应?

更新时间:2023-01-09 22:14:34

我实际上几周前我发现自己也在问同一个问题 - 正如Dirk在评论中指出的那样,@ ControllerAdvice只会在控制器方法中抛出异常时启动,所以不可避免地会抓住所有东西(我实际上是在尝试解决404错误的JSON响应的情况。)

I actually found myself asking the very same question a few weeks ago - As Dirk pointed out in the comments, @ControllerAdvice will only kick in if an exception is thrown from within a controller method, so will inevitably not catch all things (I was actually trying to solve the case for a JSON response for a 404 error).

我确定的解决方案,虽然不是很愉快(希望如果你得到更好的答案,我会改变我的方法是处理Web.xml中的错误映射 - 我添加了以下内容,它将覆盖具有特定URL映射的tomcat默认错误页面:

The solution I settled on, although not entirely pleasant (hopefully if you get a better answer I will change my approach) is handling the error mapping in the Web.xml - I added the following, which will override the tomcat default error pages with specific URL mappings:

<error-page>
    <error-code>404</error-code>
    <location>/errors/resourcenotfound</location>
</error-page>
<error-page>
    <error-code>403</error-code>
    <location>/errors/unauthorised</location>
</error-page>
<error-page>
    <error-code>401</error-code>
    <location>/errors/unauthorised</location>
</error-page>

现在,如果任何页面返回404,它将由我的错误控制器处理,如下所示:

Now, if any page returns a 404, it is handled by my error controller something like this:

@Controller
@RequestMapping("/errors")
public class ApplicationExceptionHandler {


    @ResponseStatus(HttpStatus.NOT_FOUND)
    @RequestMapping("resourcenotfound")
    @ResponseBody
    public JsonResponse resourceNotFound(HttpServletRequest request, Device device) throws Exception {
        return new JsonResponse("ERROR", 404, "Resource Not Found");
    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @RequestMapping("unauthorised")
    @ResponseBody
    public JsonResponse unAuthorised(HttpServletRequest request, Device device) throws Exception {
        return new JsonResponse("ERROR", 401, "Unauthorised Request");
    }
}

这一切仍然感觉非常严峻 - 当然是全局处理错误 - 所以如果你不总是希望404响应成为json(如果你正在服务同一个应用程序的普通webapp)那么它就不能正常工作。但就像我说的那样,我决定采取行动,这里希望有一个更好的方式!

It all still feels pretty grim - and of course is a global handling of errors - so if you didn't always want a 404 response to be json (if you were serving a normal webapp of the same application) then it doesnt work so well. But like I said, its what I settled on to get moving, here's hoping there is a nicer way!