【问题标题】:Spring Security - need 403 error, not redirectSpring Security - 需要 403 错误,而不是重定向
【发布时间】:2011-05-15 06:10:06
【问题描述】:

我正在使用 Spring Security 3.0.4。我有一堆受 Spring Security 保护的 Web 服务。当我以未经身份验证的用户身份访问它们时,Spring Security 会重定向到登录页面。相反,我想返回 HTTP 403 错误。我怎样才能做到这一点?

这是我的安全配置:

<http auto-config="false" use-expressions="true" >

    <intercept-url pattern="/authorization.jsp" access="permitAll"/>
    <intercept-url pattern="/registration.jsp" access="permitAll"/>
    <intercept-url pattern="/api/authorization/auth" access="permitAll"/>
    <intercept-url pattern="/api/authorization/new" access="permitAll"/>
    <intercept-url pattern="/api/accounts/new" access="permitAll"/>
    <intercept-url pattern="/app/**" access="permitAll"/>
    <intercept-url pattern="/extjs/**" access="permitAll"/>

    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

    <form-login login-page="/authorization.jsp"
            default-target-url="/index.jsp"
            authentication-failure-url="/registration.jsp?login_error=1"
            always-use-default-target="true"
            />

    <logout logout-success-url="/authorization.jsp"
            logout-url="/j_spring_security_logout"
            invalidate-session="true"/>        

</http>

【问题讨论】:

  • 您是否尝试过删除表单登录中的“authentication-failure-url”设置?
  • 您找到有效的解决方案了吗?我听说实现这一目标的方法是覆盖“一些 Spring 过滤器”,但没有示例,我认为应该可以配置,因为例如AJAX 应用程序喜欢在 JSON 通道上进行自定义登录,并且 JSON 通道的数据预计会在无服务权限时响应 403。

标签: spring spring-security


【解决方案1】:

对于java配置你需要做的

http.exceptionHandling().authenticationEntryPoint(alwaysSendUnauthorized401AuthenticationEntryPoint);

其中 alwaysSendUnauthorized401AuthenticationEntryPoint 是类的实例

public class AlwaysSendUnauthorized401AuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public final void commence(HttpServletRequest request, HttpServletResponse response,
                               AuthenticationException authException) throws IOException {
        LOGGER.debug("Pre-authenticated entry point called. Rejecting access");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }
}

这会禁用 Spring 的默认行为(将未经身份验证的请求重定向到登录表单)。

旁注: 对于这种情况,HTTP 代码 SC_UNAUTHORIZED(401) 比 SC_FORBIDDEN(403) 更好。

【讨论】:

  • 不确定添加的确切版本,但也有http.exceptionHandling(Customizer&lt;ExceptionHandlingConfigurer&lt;HttpSecurity&gt;&gt;),因此您可以自定义默认值。例如:http.exceptionHandling(exceptionHandling -&gt; exceptionHandling.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))。 HttpStatusEntryPoint 也很方便,因为您不需要创建自己的 AuthenticationEntrypPoint 实现。
  • 如果你不希望它总是返回一个特定的状态码,你也可以调用客户并添加一个默认入口点,它需要一个匹配器。如果匹配器匹配请求,它将使用这个入口点。例如:customizer.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), matcher),其中匹配器是任何 RequestMatcher 实现。有很多开箱即用的 RequestMatcher,所以它是一个非常灵活的选择。
【解决方案2】:

春季论坛here 上有一篇文章概述了如何让您的应用在这两种方法之间进行确定。到目前为止,我正在使用以下代码来保护我的数据控制器:

<bean id="ep403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>

<sec:http pattern="/data/**" entry-point-ref="ep403" use-expressions="true">
    <sec:intercept-url pattern="/**" access="isAuthenticated()"/>
</sec:http>

<bean id="epauth" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/login.html"/>
</bean>

<sec:http pattern="/**" entry-point-ref="epauth" use-expressions="true">
    <sec:intercept-url pattern="/**" access="isAuthenticated()"/>
</sec:http>

所以我链接的文章中的整个 DelegatingAuthenticationEntryPoint 解决方案有点重量级,但我想它也可以很好地完成工作。

【讨论】:

  • 您发布的文章中的解决方案为我解决了这个问题。谢谢!
  • 上面给出的链接(链接到 Legacy Spring 论坛)自 2019 年 2 月 28 日起已关闭。还有其他链接吗?
【解决方案3】:

你需要

  • 创建一个RequestMatcher 以确定哪些请求应该获得 403(AntPathRequestMatcher 在您的情况下可能就足够了)。
  • 配置HttpSessionRequestCache 以检查匹配器,并且不存储这些页面以进行登录后重定向。
  • 使用DelegatingAuthenticationEntryPoint 直接对请求进行 403 处理,或者根据匹配器重定向到登录。

请看这里的例子:

http://distigme.wordpress.com/2012/11/01/ajax-and-spring-security-form-based-login/

【讨论】:

    【解决方案4】:

    它应该返回 403 错误,除非您将其配置为使用此标记转到另一个 url:

    <sec:access-denied-handler error-page="/urlToGoIfForbidden" />
    

    【讨论】:

    • 是的,提问者知道应该这样做,因为他问了这个问题。他问是因为没有。
    • 此标签仅适用于没有足够 PREVILAGES 的已验证用户(文档中的内容..)
    猜你喜欢
    • 2015-08-19
    • 2017-05-10
    • 1970-01-01
    • 2017-03-21
    • 2015-07-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    相关资源
    最近更新 更多