我有一个用Spring构建的Java应用程序(jetty服务器)(MVC,安全性,事务等),并使用REST进行Web服务 . 我有另一个Java客户端使用Apache HTTPClient(HttpComponents)对服务器进行REST调用 . 服务器应用程序使用基于表单的身份验证,Web客户端使用j_spring_security_check表单登录应用程序 . 因此,从Java客户端我使用POST使用[https:// host:port / myapp / j_spring_security_check?j_username = myuser&j_password = mypass]进行登录 . 身份验证工作正常(它到达UserDetailService的子类并成功进行身份验证),但后续的REST调用失败,表明用户未经过身份验证(调用甚至没有达到给定的rest调用的控制器方法) . 我回到了应用程序的html页面之一(这是jsp页面之一) .
我正在为每个请求(包括登录)打印Cookies,并为每个请求打印不同的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吗?很感谢任何形式的帮助 .
2 回答
它's not obvious from the code snippet you showed, so I'我不确定这是否是问题,但请确保您没有为每个请求创建
new DefaultHttpClient()
,否则新客户端将有一个新的CookieStore
.首先,我想澄清一下流程 . 身份验证成功后,(Java)服务器会将JSESSIONID cookie添加到响应中 . 客户端(浏览器或其他客户端;在我们的例子中是Apache HTTP客户端)从响应中获取cookie并使用新请求发送它 . 然后,当请求访问带有cookie的服务器时 - 它可以检查请求是否经过身份验证,并且不需要身份验证 . 否则(没有cookie的请求)服务器需要身份验证 .
在您使用Apache HTTP客户端而没有cookie存储的情况下,每个请求在没有cookie的情况下发送 . 要修复它,您需要分配cookie存储 . 你应该只做一次(在PostConstructor中):
然后,使用客户端的同一实例执行调用 . 客户端将从响应中获取cookie,将其存储在cookieStore中,并将其与下一个请求一起发送 .
如果您需要任何其他说明,请告诉我 .
最好的祝福,
迈克尔