在我的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 - 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)
(...)
我没有在spring xml配置文件中添加任何异常处理细节。
我没有看到应用程序本身的任何问题,但错误是存在的,因为我是Spring MVC和Spring Security的新手,我猜我没有正确地做到这一点。有什么建议?谢谢!
答案 0 :(得分:3)
您的异常处理程序不应该抛出另一个异常。它应该处理它并发送响应。如果你从类中得到一个错误,看看它是如何表现的,那么check the code是个好主意。
对于非ajax情况,如果这是您想要的,您最好将响应重定向到登录页面。或者,您可以自定义Spring Security使用的AuthenticationEntryPoint
,并从MVC处理中省略AccessDeniedExceptions
。该行为基本上与默认LoginUrlAuthenticationEntryPoint
相同,但是当检测到ajax请求时,您会将其扩展为返回403。