/*
 * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.jersey.client.authentication;

import java.util.Base64;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.core.HttpHeaders;

import org.glassfish.jersey.client.internal.LocalizationMessages;

Implementation of Basic Http Authentication method (RFC 2617).
Author:Miroslav Fuksa, Jakub Podlesak, Craig McClanahan
/** * Implementation of Basic Http Authentication method (RFC 2617). * * @author Miroslav Fuksa * @author Jakub Podlesak * @author Craig McClanahan */
final class BasicAuthenticator { private static final Logger LOGGER = Logger.getLogger(BasicAuthenticator.class.getName()); private final HttpAuthenticationFilter.Credentials defaultCredentials;
Creates a new instance of basic authenticator.
Params:
  • defaultCredentials – Credentials. Can be null if no default credentials should be used.
/** * Creates a new instance of basic authenticator. * * @param defaultCredentials Credentials. Can be {@code null} if no default credentials should be * used. */
BasicAuthenticator(HttpAuthenticationFilter.Credentials defaultCredentials) { this.defaultCredentials = defaultCredentials; } private String calculateAuthentication(HttpAuthenticationFilter.Credentials credentials) { String username = credentials.getUsername(); byte[] password = credentials.getPassword(); if (username == null) { username = ""; } if (password == null) { password = new byte[0]; } final byte[] prefix = (username + ":").getBytes(HttpAuthenticationFilter.CHARACTER_SET); final byte[] usernamePassword = new byte[prefix.length + password.length]; System.arraycopy(prefix, 0, usernamePassword, 0, prefix.length); System.arraycopy(password, 0, usernamePassword, prefix.length, password.length); return "Basic " + Base64.getEncoder().encodeToString(usernamePassword); }
Adds authentication information to the request.
Params:
  • request – Request context.
/** * Adds authentication information to the request. * * @param request Request context. */
public void filterRequest(ClientRequestContext request) { HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter.getCredentials(request, defaultCredentials, HttpAuthenticationFilter.Type.BASIC); if (credentials == null) { LOGGER.fine(LocalizationMessages.AUTHENTICATION_CREDENTIALS_NOT_PROVIDED_BASIC()); } else { request.getHeaders().add(HttpHeaders.AUTHORIZATION, calculateAuthentication(credentials)); } }
Checks the response and if basic authentication is required then performs a new request with basic authentication.
Params:
  • request – Request context.
  • response – Response context (will be updated with newest response data if the request was repeated).
Throws:
Returns:true if response does not require authentication or if authentication is required, new request was done with digest authentication information and authentication was successful.
/** * Checks the response and if basic authentication is required then performs a new request * with basic authentication. * * @param request Request context. * @param response Response context (will be updated with newest response data if the request was repeated). * @return {@code true} if response does not require authentication or if authentication is required, * new request was done with digest authentication information and authentication was successful. * @throws ResponseAuthenticationException in case that basic credentials missing or are in invalid format */
public boolean filterResponseAndAuthenticate(ClientRequestContext request, ClientResponseContext response) { final String authenticate = response.getHeaders().getFirst(HttpHeaders.WWW_AUTHENTICATE); if (authenticate != null && authenticate.trim().toUpperCase(Locale.ROOT).startsWith("BASIC")) { HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter .getCredentials(request, defaultCredentials, HttpAuthenticationFilter.Type.BASIC); if (credentials == null) { if (response.hasEntity()) { AuthenticationUtil.discardInputAndClose(response.getEntityStream()); } throw new ResponseAuthenticationException(null, LocalizationMessages.AUTHENTICATION_CREDENTIALS_MISSING_BASIC()); } return HttpAuthenticationFilter.repeatRequest(request, response, calculateAuthentication(credentials)); } return false; } }