FORM-based Authentication
The RestClient.Builder class does not itself provide FORM-based authentication since there is no standard way of providing such support. Typically, to perform FORM-based or other types of authentication, you'll want to create your own subclass of RestClient.Builder and override the RestClient.Builder.createHttpClient() method to provide an authenticated client. The following example shows an implementation of a client that performs FORM-based authentication against the IBM Jazz platform.
/**
* Constructor.
*/
public JazzRestClient.Builder(URI jazzUri, String user, String pw) throws IOException {
...
}
/**
* Override the createHttpClient() method to return an authenticated client.
*/
@Override /* RestClient.Builder */
protected CloseableHttpClient createHttpClient() throws Exception {
CloseableHttpClient client = super.createHttpClient();
formBasedAuthenticate(client);
visitAuthenticatedURL(client);
return client;
}
/*
* Performs form-based authentication against the Jazz server.
*/
private void formBasedAuthenticate(HttpClient client) throws IOException {
URI uri2 = jazzUri.resolve("j_security_check");
HttpPost request = new HttpPost(uri2);
request.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
// Charset must explicitly be set to UTF-8 to handle user/pw with non-ascii characters.
request.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
List params = AList.of(
BasicNameValuePair.of("j_username", user),
BasicNameValuePair.of("j_password", pw)
);
request.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(request);
try {
int rc = response.getStatusLine().getStatusCode();
Header authMsg = response.getFirstHeader("X-com-ibm-team-repository-web-auth-msg");
if (authMsg != null)
throw new IOException(authMsg.getValue());
// The form auth request should always respond with a 200 ok or 302 redirect code
if (rc == SC_MOVED_TEMPORARILY) {
if (response.getFirstHeader("Location").getValue().isPattern("^.*/auth/authfailed.*$"))
throw new IOException("Invalid credentials.");
} else if (rc != SC_OK) {
throw new IOException("Unexpected HTTP status: " + rc);
}
} finally {
EntityUtils.consume(response.getEntity());
}
}
/*
* This is needed for Tomcat because it responds with SC_BAD_REQUEST when the j_security_check URL is visited before an
* authenticated URL has been visited. This same URL must also be visited after authenticating with j_security_check
* otherwise tomcat will not consider the session authenticated
*/
private int visitAuthenticatedURL(HttpClient httpClient) throws IOException {
HttpGet authenticatedURL = new HttpGet(jazzUri.resolve("authenticated/identity"));
HttpResponse response = httpClient.execute(authenticatedURL);
try {
return response.getStatusLine().getStatusCode();
} finally {
EntityUtils.consume(response.getEntity());
}
}