需要为 /login spring security 禁用 CSRF

Posted

技术标签:

【中文标题】需要为 /login spring security 禁用 CSRF【英文标题】:CSRF needs to be disabled for /login spring security 【发布时间】:2020-08-24 09:50:00 【问题描述】:

我所有的 REST 接口都可以在启用 csrf 保护的情况下正常工作,但我需要为 /login 禁用 csrf,否则我会收到 403 Forbidden。我用的是spring security,登录路径可以通过spring security获得。

http.csrf().disable() 

How to disable csrf protection for particular pages in my website?

或者如果在登录页面禁用 CSRF 没有问题,问题也将得到修复

编辑:

.csrf().ignoringAntMatchers("/login")

登录路由总是需要一个登录正文,所以应该没有 CSRF 攻击的可能性,不是吗?

【问题讨论】:

你检查了令牌的有效性吗?如果令牌过期,您可能会得到 403。您需要刷新令牌以避免这种情况。 是的,它是一个有效的令牌。其他所有请求都可以正常工作。 一般来说,如果安全机制似乎在特定任务上失败,禁用安全机制是个坏主意。并且 csrf 对您的登录来说应该不是问题。你能描述一下这个问题、你的代码库以及你到目前为止做了什么吗?我们在 Spring 上“部署”了一个 Angular Web 应用程序,其起始页面是登录页面。为了从 spring 获取有效的 csrf 令牌,我们必须从 angular 前端对任何端点进行 http-get。否则我们最终会得到 no / 无效的 csrf 令牌。也许这有帮助 登录路由总是需要一个登录主体,所以应该没有 CSRF 攻击的可能性,不是吗? 【参考方案1】:

如果您不使用 spring mvc 表单标签,则无法自动使用 spring security csrf 支持,可能您使用纯 html 表单标签,这就是您获得 http 403 的原因,您需要在表单提交中手动包含 csrf 令牌.

要么你需要像这样使用spring mvc表单标签

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
…
<form:form action="" method="POST">
…
</form:form> 

或在您的纯 html 表单提交中手动添加 csrf 令牌。

<form action="" method="POST">
<input type="hidden" name="$_csrf.parameterName" value = "$_csrf.token" />
…
</form> 

【讨论】:

【参考方案2】:

试试这个:

Spring-Security.xml 中的变化:

<security:http  use-expressions="true" authentication-manager-ref="authenticationManager">
    <security:intercept-url pattern="/auth/**" access="hasAnyRole('ROLE_USER')" />
    <security:form-login login-page="/login" authentication-success-handler-ref="loginSuccessHandler" authentication-failure-url="/login" login-processing-url="/j_spring_security_check" />
    <security:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler" />

    <security:csrf request-matcher-ref="csrfSecurityRequestMatcher"  />
</security:http>

CsrfSecurityRequestMatcher

public class CsrfSecurityRequestMatcher implements RequestMatcher 
    private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
    private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("/ext/**", null);

    @Override
    public boolean matches(HttpServletRequest request)           
        if(allowedMethods.matcher(request.getMethod()).matches())
            return false;
        
        return !unprotectedMatcher.matches(request);
    

【讨论】:

以上是关于需要为 /login spring security 禁用 CSRF的主要内容,如果未能解决你的问题,请参考以下文章

oauth2Login 和 oauth2Client 有啥区别?它们的用例是啥?

需要为 /login spring security 禁用 CSRF

spring security login csrf 失效问题

spring security

spring security 改变 spring_security_login 表单

spring security配置详解