域中的端口拒绝cookie

时间:2018-12-03 13:51:18

标签: java cookies apache-commons-httpclient

我正在连接到具有登录资源:/ login的RESTful API。使用他们给我的凭据,它会带来不错的200。 但是之后尝试访问受保护的资源会给我一个401(不过,它可以与Firefox插件RESTClient一起使用)。调试后,我发现一些cookie被拒绝是我认为的原因,这是导致我无法进入的原因。

关于它们的警告消息是:

  

Cookie拒绝了[somename =“ somevalue”,版本0,    domain:xyz.org:443 ,路径:/,到期时间:空] 非法的“ domain”属性“ xyz:443”。来源域:“ xyz”

我正在使用Apache HTTP客户端httpcomponents-client-4.5.6连接到该站点。有什么我可以做的吗?据我所知,唯一困扰的是:443。该API仅可通过https访问。我不知道是否可以使用httpclient更改对网站的访问权限,因此它不再看到域名方面的差异。

我进行了很多搜索,找到了许多有关CookieSpecProviders的过时解决方案,并将CookieSpecs设置为“简单”-但所有这些似乎完全消除了所有cookie。使用这些解决方案后,我的Cookie存储的调试输出始终为空(但警告消息消失了)。

我建立了一个快速而肮脏的孤立示例:

package apitest;

import java.io.IOException;

import org.apache.http.HttpHost;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

public class ApiTest {
    public static void main(String[] args) {
        HttpHost target = new HttpHost("stackoverflow.com", 443, "https");
        HttpClientContext context = HttpClientContext.create();
        CookieStore cookieStore = new BasicCookieStore();

        HttpClientBuilder clientBuilder = HttpClientBuilder.create().setDefaultCookieStore(cookieStore);
        CloseableHttpClient httpClient = clientBuilder.build();

        HttpGet stackGet = new HttpGet("");
        CloseableHttpResponse response;

        try {
            response = httpClient.execute(target, stackGet, context);

            printCookies(cookieStore);
        } catch (IOException e) {
            e.printStackTrace();
        }

        stackGet = new HttpGet("/tags");
        try {
            response = httpClient.execute(target, stackGet, context);

            printCookies(cookieStore);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static void printCookies(CookieStore cookieStore) {
        for (Cookie c : cookieStore.getCookies()) {
            System.out.println(c.getName() + " : " + c.getValue());
        }
    }
}

有两个连续的GET请求已完成,这将导致正确的行为。 'prov'cookie(应该是某种会话cookie)保持不变。使用上述API所做的相同操作也会导致错误。

1 个答案:

答案 0 :(得分:0)

我不知道这是否有必要,但是为了解决这个问题,我根据不同来源的建议创建了一个新的CookieSpec:

EasySpecProvider.class

import org.apache.http.cookie.CookieSpec;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.protocol.HttpContext;

class EasySpecProvider implements CookieSpecProvider {
    @Override
    public CookieSpec create(HttpContext context) {
        return new EasyCookieSpec();
    }
}

EasyCookieSpec.class

import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.impl.cookie.DefaultCookieSpec;

class EasyCookieSpec extends DefaultCookieSpec {
    @Override
    public void validate(Cookie arg0, CookieOrigin arg1) throws MalformedCookieException {
    }
}

我通过

注册了
Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()
        .register("easy", new EasySpecProvider()).build();

clientBuilder.setDefaultCookieSpecRegistry(r)
.setDefaultRequestConfig(RequestConfig.custom().setCookieSpec("easy").build())

进入客户端构建器。之后,所有格式错误的Cookie均被接受,但会话Cookie随每个请求而更改。我想同样的事情然后发生在API的服务器上(cookie的域部分不匹配)。现在,我在每个请求上清除cookie存储,并使用正确的domain属性手动重新创建会话cookie,现在它可以工作了。