4

在我的 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 很陌生,我猜我没有正确执行此操作。有什么建议么?谢谢!

4

1 回答 1

3

您的异常处理程序不应该抛出另一个异常。它应该处理它并发送响应。如果您从某个类中收到错误以查看其行为方式,最好检查代码。

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

于 2013-04-19T09:38:28.077 回答