【问题标题】:@PreAuthorize on spring controller sending redirect if authorization fails如果授权失败,弹簧控制器上的@PreAuthorize 发送重定向
【发布时间】:2010-11-11 00:04:05
【问题描述】:

我已经让 Spring Security 成功评估了我的控制器上的 @PreAuthorize。如果我使用“permitAll”,那么我可以查看该页面,如果我使用“isAuthenticated()”,那么我会得到一个丑陋的访问被拒绝堆栈跟踪。如果我将配置放在我的安全上下文配置 xml 文件中 http 节点内的拦截 url 中,那么我会很好地重定向到登录页面,而不是在我的页面中获取讨厌的堆栈跟踪。

有没有办法让我只使用注释机制来获得重定向?

【问题讨论】:

  • 为什么在安全上下文文件中有这个还不够?
  • 我只是想减少为了创建新的 url 处理程序而必须编辑的位置数量。目前,我必须编辑我的控制器类、我的上下文配置 xml 和 tukey 的 urlrewrite 配置 .xml。这不是一个交易破坏者或任何东西,但如果我能把它减少到两个位置而不是三个,下次它会容易得多。老实说,我更多的是好奇我是否可以在控制器 RequestMappings 上使用方法级别的安全性而不会失去功能。
  • 我认为这是不可能的,因为它无法区分由于根本没有登录而导致的失败和由于没有正确权限而导致的失败之间的区别。如果有人知道方法,我愿意犯错!

标签: java spring-mvc spring-security


【解决方案1】:

我得到了这个工作。有几件事我必须处理。

首先,我的 Spring MVC 配置有一个 SimpleMappingExceptionResolver 并配置了 defaultErrorView。这是在身份验证和授权错误到达我在安全配置的 http 元素中配置的访问拒绝处理程序之前拦截它们。最终代码如下所示。

securitycontext.xml

<global-method-security pre-post-annotations="enabled"/>

<!-- HTTP security configurations -->
<http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <access-denied-handler ref="myAccessDeniedHandler" />
    ... other configuration here ...
</http>

<!-- handler for authorization failure.  Will redirect to the login page. -->
<beans:bean id="myAccessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
    <beans:property name="errorPage" value="/index" />
</beans:bean>

注意 loginUrlAuthenticationEntryPoint 实际上不是解决方案的一部分,它是访问拒绝处理程序。

我的 mvc-config.xml 仍然有 SimpleMappingExceptionResolver,但没有配置 defaultErrorView。如果我要继续这条路,我可能会实现我自己的 SimpleMappingExceptionResolver,让身份验证和授权异常通过,或者在 SimpleMappingExceptionResolver 中配置它。

这笔交易的杀手锏是我还没有找到通过注解从intercept-url 配置requires-channel="https" 的方法,所以我现在将它放在xml 配置文件中无论如何。

【讨论】:

    【解决方案2】:

    您可以通过覆盖安全入口点来自定义错误处理。安全对象的过滤器链(由您在 web.xml 文件中定义的映射定义)中发生的所有异常都会被捕获并可以在那里处理。如果不处理,则 ExceptionTranslationFilter 将接管。

    您可以像这样定义自己的入口点:

    public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
    
            if (authException != null) {
                // you can check for the spefic exception here and redirect like this
                response.sendRedirect("403.html");
            }
        }
    }
    

    您可以通过将其设置为 xml 配置文件中的入口点来将其指定为入口点:

    <http entry-point-ref="customAuthenticationEntryPoint">
    
      ...
    
    </http>
    

    在您的特定情况下,PreInvocationAuthorizationAdviceVoter 将由您在配置中指定的任何 AccessDecisionManager 调用(通常是以下之一:AffirmativeBased、ConsensusBased 或 UnanimousBased)。您将看到这些 Voter 抛出 AccessDeniedException,您可以在入口点专门捕获和处理该异常。

    授予

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      相关资源
      最近更新 更多