3

我有一个用 Spring(MVC、安全、事务等)构建的 Java 应用程序(码头服务器),并将 REST 用于 Web 服务。我有另一个 Java 客户端,它使用 Apache HTTPClient (HttpComponents) 对服务器进行 REST 调用。服务器应用程序使用基于表单的身份验证,Web 客户端使用 j_spring_security_check 表单登录应用程序。因此,从 Java 客户端我使用 [https://host:port/myapp/j_spring_security_check?j_username=myuser&j_password=mypass] 使用 POST 进行登录。身份验证工作正常(它到达 UserDetailService 的子类并成功进行身份验证),但随后的 REST 调用失败,表明用户没有经过身份验证(调用甚至没有到达给定休息调用的控制器方法)。我取回了应用程序的 html 页面之一(这是 jsp 页面之一)。

我正在为每个请求(包括登录)打印 Cookie,它为每个请求打印不同的 jsessionid(请求是对服务器的其余调用)。这是cookie,每个请求一个,第一个请求是登录请求(请参阅每个请求的jsessionid不同):

cookies: [[version: 0][name: JSESSIONID][value: 1x5i3b0lbf5o7xv52kjh0vu89][domain: 127.0.0.1][path: /webui][expiry: null]]
cookies: [[version: 0][name: JSESSIONID][value: t05vbrffqv6t1xcygps9l6jaz][domain: 127.0.0.1][path: /webui][expiry: null]]
cookies: [[version: 0][name: JSESSIONID][value: 8v5i5ofbgr201kh2txxale674][domain: 127.0.0.1][path: /webui][expiry: null]]

每个请求的不同 jsessionid 是问题/原因吗?我该如何解决这个问题?这是使用 HttpClient 的代码:

    request = new HttpPost(url);
    httpClient = new DefaultHttpClient();        

    httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));

    HttpResponse response = httpClient.execute(request);
    System.out.println("cookies: " + httpClient.getCookieStore().getCookies());
    HttpEntity resp_ent = response.getEntity();
    this.status_code = response.getStatusLine().getStatusCode();

我们需要做一些特别的事情来存储cookie吗?很感谢任何形式的帮助。

4

2 回答 2

1

从您显示的代码片段中看不出来,所以我不确定这是否是问题所在,但请确保您不要new DefaultHttpClient()为每个请求创建一个,否则新客户端将有一个新的CookieStore.

于 2013-03-08T22:40:08.727 回答
0

首先,我想澄清一下流程。成功验证后,(Java)服务器将 JSESSIONID cookie 添加到响应中。客户端(浏览器或其他客户端;在我们的例子中是 Apache HTTP 客户端)从响应中获取 cookie 并将其与新请求一起发送。然后,当请求使用 cookie 访问服务器时——它可以检查请求是否经过身份验证,并且不需要身份验证。否则(没有 cookie 的请求)服务器需要身份验证。

在您的情况下,当您使用没有 cookie 的 Apache HTTP 客户端时,会存储没有 cookie 发送的每个请求。要修复它,您需要分配 cookie 存储。你应该只做一次(在 PostConstructor 中):

        httpClient = new DefaultHttpClient();
        // Create a local instance of cookie store
        cookieStore = new BasicCookieStore();
        // Set the store
        httpClient.setCookieStore(cookieStore);

然后,您使用相同的客户端实例执行调用。客户端将从响应中获取 cookie,将其存储在 cookieStore 中,并与下一个请求一起发送。

如果您需要任何其他说明,请告诉我。

最好的祝福,

迈克尔

于 2013-03-10T19:54:56.913 回答