在Spring Security中传播AccessDeniedException [英] Propagating AccessDeniedException in Spring Security

查看:1688
本文介绍了在Spring Security中传播AccessDeniedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Web应用程序中,我使用Spring Security和Spring MVC。
我已经使用 @Secured 注释和配置的Spring Security的方法,使得当没有正确角色访问这些方法之一时,用户被带到登录页面。然而,当违规请求来自Ajax时,我不希望这种行为,所以我实现了定制的 @ExceptionHandler 注释方法来确定请求的上下文。



这是我的异常处理程序:

  @ExceptionHandler(AccessDeniedException.class)
public void handleAccessDeniedException(AccessDeniedException ex,HttpServletRequest request,HttpServletResponse response)throws Exception {

if(isAjax(request)){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
throw ex;
}
}

这样我就可以自己处理异常例如,记录访问 @Secured 方法的尝试),然后让Spring执行其操作,并通过重新引用AccessDeniedException将用户重定向到登录页面。此外,当请求来自Ajax时,我将响应状态设置为 SC_UNAUTHORIZED 并处理客户端的错误。
现在,这个似乎正常工作,但是每当我从 handleAccessDeniedException 方法中重新抛出异常时,我收到以下错误:

  ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver  - 无法调用@ExceptionHandler方法:public void app.controller.BaseController.handleAccessDeniedException(org.springframework.security.access.AccessDeniedException,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)throws java.lang.Exception 
org.springframework.security .access.AccessDeniedException:
在app.controller.BaseController.handleAccessDeniedException(BaseController.java:23)
在app.controller.BaseController $$ FastClassByCGLIB $$ 8f05205​​8.invoke(< generate>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
(...)

我没有添加任何异常处理specif ics要弹出xml配置文件。



我看不到应用程序本身的任何问题,但错误在那里,因为我对Spring MVC和Spring Security很新我猜我没有这样做。有什么建议么?谢谢!

解决方案

您的异常处理程序不应该引发另一个异常。它应该处理它并发送回复。这是一个好主意,检查代码,如果您从类中收到错误,以查看它的行为。



对于非ajax案例,您最好将响应重定向到登录页面,如果这是您想要的。或者,您可以自定义Spring Security使用的 AuthenticationEntryPoint ,并从MVC处理中省略 AccessDeniedExceptions 。该行为本质上与defaul LoginUrlAuthenticationEntryPoint 相同,但是当检测到ajax请求时,您将扩展它返回403。


In my web application I am using Spring Security and Spring MVC. I have secured a couple of methods with @Secured annotation and configured Spring Security in such a way that when one of those methods is accessed without the proper role, the user is taken to the login page. However, I do not want that behaviour when the offending request comes from Ajax, so I implemented the custom @ExceptionHandler annotated method to determine the request's context.

This is my exception handler:

@ExceptionHandler(AccessDeniedException.class)
public void handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request, HttpServletResponse response) throws Exception {

    if (isAjax(request)) {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    } else {
        throw ex;
    }
}

This way I can both handle the exception myself (for example, log an attempt of accessing the @Secured method) and then let Spring do its part and redirect the user to the login page by rethrowing the AccessDeniedException. Also, when the request comes from Ajax I set the response status to SC_UNAUTHORIZED and handle the error on the client side. Now, this seems to be working fine, but I am getting the following ERROR each time I rethrow the exception from the handleAccessDeniedException method:

ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: public void app.controller.BaseController.handleAccessDeniedException(org.springframework.security.access.AccessDeniedException,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception
org.springframework.security.access.AccessDeniedException: 
    at app.controller.BaseController.handleAccessDeniedException(BaseController.java:23)
    at app.controller.BaseController$$FastClassByCGLIB$$8f052058.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    (...)

I have not added any exception handling specifics to spring xml configuration files.

I do not see any issues with the app itself, but the error is there and since I am quite new to Spring MVC and Spring Security, I am guessing that I am not doing this properly. Any suggestions? Thanks!

解决方案

Your exception handler isn't supposed to throw another exception. It's supposed to deal with it and send a response. It's a good idea to check the code if you get an error from a class to see how it behaves.

For the non-ajax case, you'd be better to redirect the response to the login page, if that's what you want. Alternatively, you can customize the AuthenticationEntryPoint used by Spring Security instead and omit AccessDeniedExceptions from MVC handling. The behaviour would essentially be the same as the defaul LoginUrlAuthenticationEntryPoint but you would extend it to return a 403 when an ajax request is detected.

这篇关于在Spring Security中传播AccessDeniedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆