Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有CSRF保护的Java Jersey POST请求_Java_Spring_Jersey_Jersey 2.0_Jersey Client - Fatal编程技术网

具有CSRF保护的Java Jersey POST请求

具有CSRF保护的Java Jersey POST请求,java,spring,jersey,jersey-2.0,jersey-client,Java,Spring,Jersey,Jersey 2.0,Jersey Client,我有一个SpringBootREST服务,它提供了一些方法。它们受CSRF和用户名/密码基本身份验证(https)保护 但是,当我尝试执行POST请求时,它失败,状态代码为403,并显示消息“无法验证提供的CSRF令牌,因为找不到您的会话” 这是我的客户代码: ApiMessage msg = new ApiMessage("Client1", "Key1", "Value1"); // Set up Basic Authentication HttpAuthentic

我有一个SpringBootREST服务,它提供了一些方法。它们受CSRF和用户名/密码基本身份验证(https)保护

但是,当我尝试执行POST请求时,它失败,状态代码为403,并显示消息“无法验证提供的CSRF令牌,因为找不到您的会话”

这是我的客户代码:

    ApiMessage msg = new ApiMessage("Client1", "Key1", "Value1");

    // Set up Basic Authentication
    HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder()
            .nonPreemptive()
            .credentials(ApiUser, ApiUserPassword)
            .build();
    ClientConfig clientConfig = new ClientConfig();
    clientConfig.register(feature);
    Client client = ClientBuilder.newClient(clientConfig);

    // Set up client and target (ApiHost = URI for the request Ressource)
    WebTarget target = client.target(ApiHost);
    WebTarget checkTarget = target.path("check");
    Invocation.Builder invocationBuilder = checkTarget.request(MediaType.APPLICATION_JSON);

    // Do a first request to get the CSRF Header
    Response response = invocationBuilder.post(Entity.entity(msg, MediaType.APPLICATION_JSON));

    if (response.getStatus() == 200) {

        System.out.println("Without CSRF - everything worked. ");

    } else if (response.getStatus() == 403) {

        System.out.println("CSRF Protection: " + response.getStatus() + response.readEntity(String.class));

        // Get CSRF Token out of the response
        Map<String, NewCookie> cookies = response.getCookies();
        String csrf = cookies.get("XSRF-TOKEN").getValue();

        // Add the Token to the header and POST again
        invocationBuilder.header("X-XSRF-TOKEN", csrf);
        response = invocationBuilder.post(Entity.entity(msg, MediaType.APPLICATION_JSON));

        if (response.getStatus() != 200) {
            System.out.println("Error: " + response.getStatus() + response.readEntity(String.class));
        } else {
            System.out.println("With CSRF - everything worked. ");
        }
    } else {
        System.out.println(response.getStatus() + " " + response.readEntity(String.class));
    }
ApiMessage msg=新的ApiMessage(“Client1”、“Key1”、“Value1”);
//设置基本身份验证
HttpAuthenticationFeature=HttpAuthenticationFeature.basicBuilder()
.非强制性的
.凭据(ApiUser、ApiUserPassword)
.build();
ClientConfig ClientConfig=new ClientConfig();
clientConfig.register(功能);
Client Client=ClientBuilder.newClient(clientConfig);
//设置客户端和目标(请求资源的ApiHost=URI)
WebTarget=client.target(ApiHost);
WebTarget checkTarget=target.path(“检查”);
Invocation.Builder invocationBuilder=checkTarget.request(MediaType.APPLICATION\ujson);
//执行第一个请求以获取CSRF头
Response-Response=invocationBuilder.post(Entity.Entity(msg,MediaType.APPLICATION_JSON));
if(response.getStatus()==200){
System.out.println(“没有CSRF-一切正常”);
}else if(response.getStatus()==403){
System.out.println(“CSRF保护:+response.getStatus()+response.readEntity(String.class));
//从响应中获取CSRF令牌
映射cookies=response.getCookies();
字符串csrf=cookies.get(“XSRF-TOKEN”).getValue();
//将令牌添加到标题并再次发布
invocationBuilder.header(“X-XSRF-TOKEN”,csrf);
response=invocationBuilder.post(Entity.Entity(msg,MediaType.APPLICATION_JSON));
if(response.getStatus()!=200){
System.out.println(“错误:+response.getStatus()+response.readEntity(String.class));
}否则{
System.out.println(“使用CSRF-一切正常”);
}
}否则{
System.out.println(response.getStatus()+“”+response.readEntity(String.class));
}
第一个请求以状态403结束,消息“无法验证提供的CSRF令牌,因为找不到您的会话”。 之后,我成功地从响应头中提取CSRF令牌。 但是,第二个带有CSRF头的请求失败,并出现相同的错误

在邮递员身上做同样的事也行


知道我的错误在哪里吗?我做错了什么吗?

可能还有一个会话cookie需要发送回去,比如JSESSIONID。拿那块饼干。从
NewCookie
创建
Cookie
,并将其添加到请求中

NewCookie session = cookies.get("JSESSIONID");
Cookie cookie = session.toCookie();
invocationBuilder.cookie(cookie);

如果不是JSESSIONID,请检查所有cookies。可能是其他原因。

调用Map cookies=response.getCookies()时,只有一个Cookie返回;在《邮差》中,我可以看到两个cookie:XSRF-TOKEN和JSESSIONID。但是在我的Java客户机中,我只得到XSRF令牌,这很奇怪。我将在稍后进行测试。首先,我对我喜欢访问的资源执行POST请求,并对其进行基本身份验证。我得到了两个cookie:XSRF-TOKEN和JSESSIONID。然后,我用cookie XSRF-TOKEN的值设置头X-XSRF-TOKEN,并将POST请求重新发送到同一个资源,您在Postman中第一个请求返回的请求是403?这就是你上面的代码所暗示的。是的,邮递员的第一个答案是403。第二个请求(带有CSRF头)以200结尾。