java 无法验证提供的 CSRF 令牌,因为未找到您的会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38886190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:52:03  来源:igfitidea点击:

Could not verify the provided CSRF token because your session was not found

javaspringspring-mvcspring-security

提问by FreezY

I've been searching about this problem but still cannot be avoid. The problem only come when I'm trying to make an ajax call. The system will return error Could not verify the provided CSRF token because your session was not found.

我一直在寻找这个问题,但仍然无法避免。问题仅在我尝试进行 ajax 调用时出现。系统会返回错误Could not verify the provided CSRF token because your session was not found.

Based from Spring MVC and CSRF Integration, I need to included @EnableWebSecurityto resolve this if I'm using Java Config, but if using XML, need to use this :

基于Spring MVC 和 CSRF 集成,如果我使用 Java Config ,我需要包含@EnableWebSecurity来解决这个问题,但如果使用 XML,需要使用这个:

@RestController
public class CsrfController {

    @RequestMapping("/csrf")
    public CsrfToken csrf(CsrfToken token) {
        return token;
    }
}

And I'm not sure how to use above class.

而且我不确定如何使用上面的课程。

The question is how to use above class if its really a solution or are there any solution I can use?

问题是如何使用上面的课程,如果它真的是一个解决方案,或者有什么我可以使用的解决方案?

This is my security config xml file;

这是我的安全配置 xml 文件;

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- Global Security Settings -->
    <global-method-security pre-post-annotations="enabled" />
    <context:component-scan base-package="com.my.web" />

    <!-- Reads WEB Configuration file to resolve ${} and read @Value for Security-->
    <context:property-placeholder location="classpath:cfg/web.cfg" />
    <context:annotation-config />

    <!-- Security Access Configuration -->

    <http auto-config="false" use-expressions="true" authentication-manager-ref="CAP" disable-url-rewriting="true" entry-point-ref="IAE">

        <session-management  session-fixation-protection="newSession" session-authentication-error-url="/logout?timeout" >
            <concurrency-control max-sessions="1" expired-url="/logout?expired" />
        </session-management>
        <custom-filter position="PRE_AUTH_FILTER" ref="entryFilter" />
        <intercept-url pattern="/resources/**" access="permitAll()" requires-channel="https" />
        <intercept-url pattern="/clearcache" access="permitAll()" requires-channel="https" />
        <intercept-url pattern="/logout" access="permitAll()" requires-channel="https" />
        <intercept-url pattern="/**" access="isFullyAuthenticated()" requires-channel="https" />

        <port-mappings >
            <port-mapping http="7001" https="7002"  />
        </port-mappings>

    <headers>
        <frame-options policy="SAMEORIGIN" />
        <hsts />
        <cache-control />
        <xss-protection />
        <content-type-options />
    </headers>

    </http>

    <beans:bean id="entryFilter" class="com.my.web.security.HeaderFilter" >
        <beans:property name="authenticationManager" ref="CAP"/>
        </beans:bean>
    <beans:bean id="IAE" class="com.my.web.security.CustomAuthenticationEntryPoint" />
    <beans:bean id="CAP" class="com.my.web.security.CustomAuthenticationManager" />

    <beans:import resource="../aop/aspect-security.xml" />
</beans:beans>

In addition, I'm a using system similar like CA Siteminder which will validated the user based on header info with no login form.

此外,我是一个类似于 CA Siteminder 的使用系统,它将根据标题信息验证用户,而无需登录表单。

采纳答案by FreezY

THIS IS THE ANSWER!

这就是答案!

Ok so here the thing, from other question that literally have the same cause, mostly it will affect system that using Rest, headerwithout form login. This mean that the webapp is in the container system. So the location of both system either container and the system in the container is completely different at client side.

好的,这里的事情,从字面上有相同原因的其他问题来看,主要是它会影响使用Restheader而无需表单登录的系统。这意味着 webapp 在容器系统中。因此,无论是容器还是容器中的系统在客户端的位置都完全不同。

Here are the example..

这是例子..

For container webapp:

对于容器 webapp:

 www.myweb.com/main/

For webapp in container:

对于容器中的 webapp:

www.myweb.com/main/child

This different will denied the access and give the 403 because for sure the this we are looking in are not exist there.

这个不同的将拒绝访问并给出 403 因为肯定我们正在寻找的这个不存在那里。

Example:

例子:

www.myweb.com/main/child/playground

The /playgrounduri is exist there but for sure is forbidden here:

/playgroundURI是存在那里,但可以肯定的是这里禁止:

www.myweb.com/main/playground

So please check your uri and try to make sure you are using a relative path. Its much more better.

因此,请检查您的 uri 并尝试确保您使用的是相对路径。它更好。

P/s:For some reason, everything that being called from server side remain intact either the container or the system in the container.This happen because the server side using relative path,not absolute path.

P/s:出于某种原因,从服务器端调用的所有内容在容器或容器中的系统都保持不变。发生这种情况是因为服务器端使用的是相对路径,而不是绝对路径。

回答by A. Saladino

Spring requires sending the csrf token on every form submit. To accomplish this is possible for example to insert the following code into a JSP:

Spring 要求在每次提交表单时发送 csrf 令牌。例如,为了实现这一点,可以将以下代码插入 JSP:

<form>
[...]
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 
[...]
</form>

Best regards

最好的祝福

回答by JayDee101

I' new to SO and this is my first answer, so bear with me. This is what has to be done before doing AJAX calls when using jQuery:

我是新来的,这是我的第一个答案,所以请耐心等待。这是在使用 jQuery 时执行 AJAX 调用之前必须完成的操作:

$(document).ready(

        function() {

            var token = $("meta[name='_csrf']").attr("content");

            $.ajaxSetup({
                headers : {
                    "X-CSRF-Token" : token
                }
            });

});