eclipse-ee4j / eclipse-ee4j/jersey
SslContext and HostVerifier not passed on nonPreemptive auth
- Dominant language
- Java
- Stars
- 730
- Forks
- 382
- PR merge metrics
- No merged PRs in 30d
Description
The SslContext and the HostVerifier are not passed when the WS is using a BASIC authentication and nonPreemptive is used. The request is repeated (with authorization header) but both settings are not passed, so the second attempt with BASIC header can fail because security reasons (SSL certs or hostname verification).
This is a sample code for testing:
```
static public void main(String[] args) throws Exception {
ClientBuilder clientBuilder = ClientBuilder.newBuilder();
SSLContext sc = SSLContext.getInstance("SSL");
TrustManager[] trustAllCerts = {new InsecureTrustManager()};
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HostnameVerifier allHostsValid = new InsecureHostnameVerifier();
Client client = clientBuilder.sslContext(sc).hostnameVerifier(allHostsValid).build();
client.register(HttpAuthenticationFeature.basicBuilder()
// comment this line or not to checl the bug
.nonPreemptive()
.credentials("ricky", "Kiosko_00").build());
Response response = client.target("https://localhost:8181/jaxrs-sample")
.path("webresources")
.path("hellows")
.path("sayhello")
.queryParam("name", "ricky")
.request()
.get();
if (response.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)) {
System.out.println(response.readEntity(String.class));
} else {
throw new Exception(String.format("HTTP error (%d): %s", response.getStatus(),
response.getStatusInfo().getReasonPhrase()));
}
}
```
I have check the code of version 2.6 and the issue is quite issue to fix. Here it is a tentative patch:
```
*** ./org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java.ORIG 2014-02-28 10:48:41.678462757 +0100
--- ./org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java 2014-02-28 10:48:13.322008734 +0100
*************** class HttpAuthenticationFilter implement
*** 296,302 ****
*
*/
static boolean repeatRequest(ClientRequestContext request, ClientResponseContext response, String newAuthorizationHeader) {
! Client client = ClientBuilder.newClient(request.getConfiguration());
String method = request.getMethod();
MediaType mediaType = request.getMediaType();
URI lUri = request.getUri();
--- 296,306 ----
*
*/
static boolean repeatRequest(ClientRequestContext request, ClientResponseContext response, String newAuthorizationHeader) {
! Client client = ClientBuilder.newBuilder()
! .hostnameVerifier(request.getClient().getHostnameVerifier())
! .sslContext(request.getClient().getSslContext())
! .withConfig(request.getConfiguration())
! .build();
String method = request.getMethod();
MediaType mediaType = request.getMediaType();
URI lUri = request.getUri();
```
As you see the repeatRequest method now uses SslContext, HostnameVerifier and the configuration of the original request. With this patch my simple testcase works no matter it is preemptive or not.
#### Environment
OS:
Linux 3.12-1-amd64 #1 SMP Debian 3.12.9-1 (2014-02-01) x86_64 GNU/Linux
JAVA:
java version "1.7.0_25"
OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1~deb7u1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
#### Affected Versions
[2.6]
Contributor guide
Assessment
This issue has not been assessed yet.