The following example shows an implementation of a client that performs OIDC 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();
| oidcAuthenticate(client);
| return client;
| }
|
| private void oidcAuthenticate(HttpClient client) throws IOException {
|
| HttpGet request = new HttpGet(jazzUri);
| 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");
|
| HttpResponse response = client.execute(request);
| try {
| int code = response.getStatusLine().getStatusCode();
|
| // Already authenticated
| if (code == SC_OK)
| return;
|
| if (code != SC_UNAUTHORIZED)
| throw new RestCallException("Unexpected response during OIDC authentication: "
| + response.getStatusLine());
|
| // x-jsa-authorization-redirect
| String redirectUri = getHeader(response, "X-JSA-AUTHORIZATION-REDIRECT");
|
| if (redirectUri == null)
| throw new RestCallException("Expected a redirect URI during OIDC authentication: "
| + response.getStatusLine());
|
| // Handle Bearer Challenge
| HttpGet method = new HttpGet(redirectUri + "&prompt=none");
| addDefaultOidcHeaders(method);
|
| response = client.execute(method);
|
| code = response.getStatusLine().getStatusCode();
|
| if (code != SC_OK)
| throw new RestCallException("Unexpected response during OIDC authentication phase 2: "
| + response.getStatusLine());
|
| String loginRequired = getHeader(response, "X-JSA-LOGIN-REQUIRED");
|
| if (! "true".equals(loginRequired))
| throw new RestCallException("X-JSA-LOGIN-REQUIRED header not found on response during OIDC authentication phase 2: "
| + response.getStatusLine());
|
| method = new HttpGet(redirectUri + "&prompt=none");
|
| addDefaultOidcHeaders(method);
| response = client.execute(method);
|
| code = response.getStatusLine().getStatusCode();
|
| if (code != SC_OK)
| throw new RestCallException("Unexpected response during OIDC authentication phase 3: "
| + response.getStatusLine());
|
| // Handle JAS Challenge
| method = new HttpGet(redirectUri);
| addDefaultOidcHeaders(method);
|
| response = client.execute(method);
|
| code = response.getStatusLine().getStatusCode();
|
| if (code != SC_OK)
| throw new RestCallException("Unexpected response during OIDC authentication phase 4: "
| + response.getStatusLine());
|
| cookie = getHeader(response, "Set-Cookie");
|
| Header[] defaultHeaders = new Header[] {
| BasicStringHeader.of("User-Agent", "Jazz Native Client"),
| BasicStringHeader.of("X-com-ibm-team-configuration-versions",
| "com.ibm.team.rtc=6.0.0,com.ibm.team.jazz.foundation=6.0"),
| BasicStringHeader.of("Accept", "text/json"),
| BasicStringHeader.of("Authorization", "Basic "
| + StringUtils.base64EncodeToString(user + ":" + pw)),
| BasicStringHeader.of("Cookie", cookie)
| };
|
| setDefaultHeaders(AList.of(defaultHeaders));
|
| } finally {
| EntityUtils.consume(response.getEntity());
| }
| }
|
| private void addDefaultOidcHeaders(HttpRequestBase method) {
| method.addHeader("User-Agent", "Jazz Native Client");
| method.addHeader("X-com-ibm-team-configuration-versions",
| "com.ibm.team.rtc=6.0.0,com.ibm.team.jazz.foundation=6.0");
| method.addHeader("Accept", "text/json");
|
| if (cookie != null) {
| method.addHeader("Authorization", "Basic "
| + StringUtils.base64EncodeToString(user + ":" + pw));
| method.addHeader("Cookie", cookie);
| }
| }