【问题标题】:Spring @ExceptionHandler does not catch AccessDeniedExceptionSpring @ExceptionHandler 没有捕获 AccessDeniedException
【发布时间】:2013-01-03 15:33:15
【问题描述】:

我有一个使用以下代码设置的异常处理程序

@ExceptionHandler(Throwable.class)
public @ResponseBody CustomResponse handleException(Throwable throwable){
    // handles exception, returns a JSON
}

我正在使用 Spring Security 3.1。当我尝试在没有身份验证的情况下执行操作时,应用程序会引发 AccessDeniedException。它永远不会用到这种方法。但适用于其他例外情况。这是它应该工作的方式吗?还是我的代码有问题?

This 看起来像是一个解决方案。但是如果我能在一个点上处理异常会更好。

这是我的配置文件

<global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />
<http auto-config="true" use-expressions="true">
    //intercept urls
    <form-login login-page="/signin" default-target-url="/" always-use-default-target="true"/>
</http>

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder ref="encoder" />
    </authentication-provider>
</authentication-manager>

<!-- This encoder doesn't require a salt -->
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

更新

此处用户未通过身份验证 (ROLE_ANONYMOUS)。当我尝试访问受保护的页面时,它会将我重定向到登录 URL。我的问题是,我进行了 AJAX 调用。所以重定向到返回 ModelAndView 的方法是行不通的。这里有工作吗?

【问题讨论】:

    标签: java spring spring-mvc spring-security


    【解决方案1】:

    Spring Security 的请求处理全部发生在过滤器链中,在调用调度程序 servlet 之前,因此它对 Spring MVC 异常处理程序一无所知,实际上完全可以在没有 Spring MVC 的情况下使用。

    您看到的是 expected behaviour 用于未经身份验证的用户,但您不希望将 Ajax 调用重定向到 UI 代码。很难确切地说出最佳解决方案是什么,因为对于未经身份验证的 ajax 调用,您希望行为是什么并不明显。例如,如果您希望它们简单地以 403 失败,那么您可以将 ajax api 分离到一个单独的过滤器链中。例如,如果您的 ajax 调用是对 /ajaxapi 的调用,则可以在现有定义之前添加以下链定义:

    <http pattern="/ajaxapi/**" create-session="never" use-expressions="true" entry-point-ref="entryPoint">
        <intercept-url pattern="/**" access="isAuthenticated()" />
    </http>
    
    <bean entryPoint="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
    

    然后,所有 ajax 调用都会得到 403 响应,直到用户通过浏览器界面进行身份验证。

    【讨论】:

    • 谢谢明白了。我想做我对所有其他异常所做的事情,即返回 JSON 响应。有没有办法在 AccessDeniedHandler 中做类似的事情?
    • 可以写一个自定义的AuthenticationEntryPoint,在上面的sn-p中使用。以Http403ForbiddenEntryPoint 为起点。
    • 知道了 :) 我不必编写自定义的 AuthenticationEntryPoint。一个简单的 403 响应就足够了。谢谢顺便说一句。
    • 您是如何解决问题的?可以分享一下你的配置吗?我有同样的问题,我无法捕获 AccessDeniedException(甚至是授权过程中的其他抛出)
    【解决方案2】:

    我猜你在 spring 安全配置中定义了一个&lt;access-denied-handler&gt;。这个处理程序正在捕获AccessDeniedException。 这可能就是为什么你没有在你的通用 ExceptionHandler 中得到它。

    有一个默认的 AccessDeniedHandler(带有默认的 spring 安全设置)。请阅读this了解更多详情。

    【讨论】:

    • 我认为当用户已经通过身份验证然后他正在访问他不应该访问的东西时会调用它。那不是我的情况。我已经更新了。
    猜你喜欢
    • 1970-01-01
    • 2017-12-07
    • 2016-12-16
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    相关资源
    最近更新 更多