【问题标题】:Spring not sending CSRF token on responseSpring 未在响应时发送 CSRF 令牌
【发布时间】:2016-08-03 11:31:52
【问题描述】:

我在让我的 Angular2 客户端与我的 Spring 服务器通信时遇到问题,因为我向它添加了 spring-security,即当我尝试向服务器登录 url 发送包含身份验证信息的 JSON 时,我得到一个 403“Invalid CSRF在请求参数 '_csrf' 或标头 'X-CSRF-TOKEN' 上找到令牌 'null'。”

我知道我应该在我的响应的标题上传递一个令牌以供客户端使用,但这个令牌没有被传递。我尝试了this answer,但令牌仍未通过。我也在通过邮递员发送请求,但令牌也没有到达。

webSecurityConfig.xml:

    <http entry-point-ref="restAuthenticationEntryPoint">
      <intercept-url pattern="/api/**" access="hasRole('ROLE_USER')"/>

      <form-login
         authentication-success-handler-ref="mySuccessHandler"
         authentication-failure-handler-ref="myFailureHandler"
      />

      <logout />
   </http>

   <beans:bean id="mySuccessHandler"
      class="com.eficid.cloud.security.rest.AuthenticationSuccessHandler"/>
   <beans:bean id="myFailureHandler" class=
     "org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"/>


      <authentication-manager>
        <authentication-provider>
          <user-service>
            <user name="temp" password="temp" authorities="ROLE_USER" />
          </user-service>
        </authentication-provider>
      </authentication-manager>

</beans:beans>

SpringSecurityConfiguration

@Configuration
@ImportResource({ "classpath:webSecurityConfig.xml" })
@ComponentScan("com.eficid.cloud.security.rest")
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    public SpringSecurityConfig() {
        super();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests()
                .antMatchers("/spring-security-rest/login").permitAll().anyRequest()
                .authenticated().and().csrf()
                .csrfTokenRepository(csrfTokenRepository()).and()
                .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
    }


    private Filter csrfHeaderFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                        .getName());
                if (csrf != null) {
                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                    String token = csrf.getToken();
                    if (cookie == null || token != null
                            && !token.equals(cookie.getValue())) {
                        cookie = new Cookie("XSRF-TOKEN", token);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }
                }
                filterChain.doFilter(request, response);
            }
        };
    }

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }

}

【问题讨论】:

    标签: spring spring-security csrf


    【解决方案1】:

    可能有错别字:

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }
    

    必须是 X-CSRF-TOKEN 而不是 X-XSRF-TOKEN。建议重构。

    查看此链接:How to access Spring CSRF restful web service

    【讨论】:

    • 响应中仍未传递标头
    • 你检查过cookie中是否有csrf吗?
    • 我做了,没有返回cookie
    猜你喜欢
    • 2018-05-10
    • 2018-03-20
    • 2019-07-20
    • 2019-01-30
    • 2018-08-27
    • 2018-08-19
    • 2015-03-26
    • 1970-01-01
    • 2021-06-16
    相关资源
    最近更新 更多