All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.jersey.client.authentication.HttpAuthenticationFeature Maven / Gradle / Ivy

Go to download

A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle (jaxrs-ri.jar). Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from the command line.

There is a newer version: 3.1.6
Show newest version
/*
 * Copyright (c) 2013, 2020 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 jakarta.ws.rs.core.Feature;
import jakarta.ws.rs.core.FeatureContext;

/**
 * Features that provides Http Basic and Digest client authentication (based on RFC 2617).
 * 

* The feature can work in following modes: *

    *
  • BASIC: Basic preemptive authentication. In preemptive mode the authentication information * is send always with each HTTP request. This mode is more usual than the following non-preemptive mode * (if you require BASIC authentication you will probably use this preemptive mode). This mode must * be combined with usage of SSL/TLS as the password is send only BASE64 encoded.
  • *
  • BASIC NON-PREEMPTIVE: Basic non-preemptive authentication. In non-preemptive mode the * authentication information is added only when server refuses the request with {@code 401} status code and * then the request is repeated with authentication information. This mode has negative impact on the performance. * The advantage is that it does not send credentials when they are not needed. This mode must * be combined with usage of SSL/TLS as the password is send only BASE64 encoded. *

    * Please note that when you use non-preemptive authentication, Jersey client will make 2 requests to a resource, * which also means that all registered filters will be invoked twice. *

  • *
  • DIGEST: Http digest authentication. Does not require usage of SSL/TLS.
  • *
  • UNIVERSAL: Combination of basic and digest authentication. The feature works in non-preemptive * mode which means that it sends requests without authentication information. If {@code 401} status * code is returned, the request is repeated and an appropriate authentication is used based on the * authentication requested in the response (defined in {@code WWW-Authenticate} HTTP header. The feature * remembers which authentication requests were successful for given URI and next time tries to preemptively * authenticate against this URI with latest successful authentication method. *
  • *
*

*

* To initialize the feature use static method of this feature. *

*

* Example of building the feature in * Basic authentication mode: *

 * HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("user", "superSecretPassword");
 * 
*

*

* Example of building the feature in basic non-preemptive mode: *

 * HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder()
 *     .nonPreemptive().credentials("user", "superSecretPassword").build();
 * 
*

*

* Example of building the feature in universal mode: *

 * HttpAuthenticationFeature feature = HttpAuthenticationFeature.universal("user", "superSecretPassword");
 * 
*

*

* Example of building the feature in universal mode with different credentials for basic and digest: *

 * HttpAuthenticationFeature feature = HttpAuthenticationFeature.universalBuilder()
 *      .credentialsForBasic("user", "123456")
 *      .credentials("adminuser", "hello")
 *      .build();
 * 
*

* Example of building the feature in basic preemptive mode with no default credentials. Credentials will have * to be supplied with each request using request properties (see below): *
 * HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().build();
 * 
*

*

* Once the feature is built it needs to be registered into the {@link jakarta.ws.rs.client.Client}, * {@link jakarta.ws.rs.client.WebTarget} or other client configurable object. Example: *

 * final Client client = ClientBuilder.newClient();
 * client.register(feature);
 * 
*

* * Then you invoke requests as usual and authentication will be handled by the feature. * You can change the credentials for each request using properties * {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature#HTTP_AUTHENTICATION_USERNAME} and * {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature#HTTP_AUTHENTICATION_PASSWORD}. Example: *
 * final Response response = client.target("http://localhost:8080/rest/homer/contact").request()
 *    .property(HTTP_AUTHENTICATION_BASIC_USERNAME, "homer")
 *    .property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "p1swd745").get();
 * 
*

* This class also contains property key definitions for overriding only specific basic or digest credentials: *

    *
  • * {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature#HTTP_AUTHENTICATION_BASIC_USERNAME} and * {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature#HTTP_AUTHENTICATION_BASIC_PASSWORD} *
  • *
  • * {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature#HTTP_AUTHENTICATION_DIGEST_USERNAME} and * {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature#HTTP_AUTHENTICATION_DIGEST_PASSWORD}. *
  • *
*

* * @author Miroslav Fuksa * * @since 2.5 */ public class HttpAuthenticationFeature implements Feature { /** * Feature authentication mode. */ static enum Mode { /** * Basic preemptive. **/ BASIC_PREEMPTIVE, /** * Basic non preemptive */ BASIC_NON_PREEMPTIVE, /** * Digest. */ DIGEST, /** * Universal. */ UNIVERSAL } /** * Builder that creates instances of {@link HttpAuthenticationFeature}. */ public static interface Builder { /** * Set credentials. * * @param username Username. * @param password Password as byte array. * @return This builder. */ public Builder credentials(String username, byte[] password); /** * Set credentials. * * @param username Username. * @param password Password as {@link String}. * @return This builder. */ public Builder credentials(String username, String password); /** * Build the feature. * * @return Http authentication feature configured from this builder. */ public HttpAuthenticationFeature build(); } /** * Extension of {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.Builder} * that builds the http authentication feature configured for basic authentication. */ public static interface BasicBuilder extends Builder { /** * Configure the builder to create features in non-preemptive basic authentication mode. * * @return This builder. */ public BasicBuilder nonPreemptive(); } /** * Extension of {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.Builder} * that builds the http authentication feature configured in universal mode that supports * basic and digest authentication. */ public static interface UniversalBuilder extends Builder { /** * Set credentials that will be used for basic authentication only. * * @param username Username. * @param password Password as {@link String}. * @return This builder. */ public UniversalBuilder credentialsForBasic(String username, String password); /** * Set credentials that will be used for basic authentication only. * * @param username Username. * @param password Password as {@code byte array}. * @return This builder. */ public UniversalBuilder credentialsForBasic(String username, byte[] password); /** * Set credentials that will be used for digest authentication only. * * @param username Username. * @param password Password as {@link String}. * @return This builder. */ public UniversalBuilder credentialsForDigest(String username, String password); /** * Set credentials that will be used for digest authentication only. * * @param username Username. * @param password Password as {@code byte array}. * @return This builder. */ public UniversalBuilder credentialsForDigest(String username, byte[] password); } /** * Implementation of all authentication builders. */ static class BuilderImpl implements UniversalBuilder, BasicBuilder { private String usernameBasic; private byte[] passwordBasic; private String usernameDigest; private byte[] passwordDigest; private Mode mode; /** * Create a new builder. * * @param mode Mode in which the final authentication feature should work. */ public BuilderImpl(Mode mode) { this.mode = mode; } @Override public Builder credentials(String username, String password) { return credentials(username, password == null ? null : password.getBytes(HttpAuthenticationFilter.CHARACTER_SET)); } @Override public Builder credentials(String username, byte[] password) { credentialsForBasic(username, password); credentialsForDigest(username, password); return this; } @Override public UniversalBuilder credentialsForBasic(String username, String password) { return credentialsForBasic(username, password == null ? null : password.getBytes(HttpAuthenticationFilter.CHARACTER_SET)); } @Override public UniversalBuilder credentialsForBasic(String username, byte[] password) { this.usernameBasic = username; this.passwordBasic = password; return this; } @Override public UniversalBuilder credentialsForDigest(String username, String password) { return credentialsForDigest(username, password == null ? null : password.getBytes(HttpAuthenticationFilter.CHARACTER_SET)); } @Override public UniversalBuilder credentialsForDigest(String username, byte[] password) { this.usernameDigest = username; this.passwordDigest = password; return this; } @Override public HttpAuthenticationFeature build() { return new HttpAuthenticationFeature(mode, usernameBasic == null ? null : new HttpAuthenticationFilter.Credentials(usernameBasic, passwordBasic), usernameDigest == null ? null : new HttpAuthenticationFilter.Credentials(usernameDigest, passwordDigest)); } @Override public BasicBuilder nonPreemptive() { if (mode == Mode.BASIC_PREEMPTIVE) { this.mode = Mode.BASIC_NON_PREEMPTIVE; } return this; } } /** * Key of the property that can be set into the {@link jakarta.ws.rs.client.ClientRequestContext client request} * using {@link jakarta.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override * the username for http authentication feature for the request. *

* Example: *

     * Response response = client.target("http://localhost:8080/rest/joe/orders").request()
     *      .property(HTTP_AUTHENTICATION_USERNAME, "joe")
     *      .property(HTTP_AUTHENTICATION_PASSWORD, "p1swd745").get();
     * 
*

* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property * (as shown in the example). This property pair overrides all password settings of the authentication * feature for the current request. *

* The default value must be instance of {@link String}. *

*

* The name of the configuration property is {@value}. *

*/ public static final String HTTP_AUTHENTICATION_USERNAME = "jersey.config.client.http.auth.username"; /** * Key of the property that can be set into the {@link jakarta.ws.rs.client.ClientRequestContext client request} * using {@link jakarta.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override * the password for http authentication feature for the request. *

* Example: *

     * Response response = client.target("http://localhost:8080/rest/joe/orders").request()
     *      .property(HTTP_AUTHENTICATION_USERNAME, "joe")
     *      .property(HTTP_AUTHENTICATION_PASSWORD, "p1swd745").get();
     * 
*

* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_USERNAME} property * (as shown in the example). This property pair overrides all password settings of the authentication * feature for the current request. *

* The value must be instance of {@link String} or {@code byte} array ({@code byte[]}). *

*

* The name of the configuration property is {@value}. *

*/ public static final String HTTP_AUTHENTICATION_PASSWORD = "jersey.config.client.http.auth.password"; /** * Key of the property that can be set into the {@link jakarta.ws.rs.client.ClientRequestContext client request} * using {@link jakarta.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override * the username for http basic authentication feature for the request. *

* Example: *

     * Response response = client.target("http://localhost:8080/rest/joe/orders").request()
     *      .property(HTTP_AUTHENTICATION_BASIC_USERNAME, "joe")
     *      .property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "p1swd745").get();
     * 
*

* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property * (as shown in the example). The property pair influence only credentials used during basic authentication. * *

* The value must be instance of {@link String}. *

*

* The name of the configuration property is {@value}. *

*/ public static final String HTTP_AUTHENTICATION_BASIC_USERNAME = "jersey.config.client.http.auth.basic.username"; /** * Key of the property that can be set into the {@link jakarta.ws.rs.client.ClientRequestContext client request} * using {@link jakarta.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override * the password for http basic authentication feature for the request. *

* Example: *

     * Response response = client.target("http://localhost:8080/rest/joe/orders").request()
     *      .property(HTTP_AUTHENTICATION_BASIC_USERNAME, "joe")
     *      .property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "p1swd745").get();
     * 
*

* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_USERNAME} property * (as shown in the example). The property pair influence only credentials used during basic authentication. *

* The value must be instance of {@link String} or {@code byte} array ({@code byte[]}). *

*

* The name of the configuration property is {@value}. *

*/ public static final String HTTP_AUTHENTICATION_BASIC_PASSWORD = "jersey.config.client.http.auth.basic.password"; /** * Key of the property that can be set into the {@link jakarta.ws.rs.client.ClientRequestContext client request} * using {@link jakarta.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override * the username for http digest authentication feature for the request. *

* Example: *

     * Response response = client.target("http://localhost:8080/rest/joe/orders").request()
     *      .property(HTTP_AUTHENTICATION_DIGEST_USERNAME, "joe")
     *      .property(HTTP_AUTHENTICATION_DIGEST_PASSWORD, "p1swd745").get();
     * 
*

* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property * (as shown in the example). The property pair influence only credentials used during digest authentication. *

* The value must be instance of {@link String}. *

*

* The name of the configuration property is {@value}. *

*/ public static final String HTTP_AUTHENTICATION_DIGEST_USERNAME = "jersey.config.client.http.auth.digest.username"; /** * Key of the property that can be set into the {@link jakarta.ws.rs.client.ClientRequestContext client request} * using {@link jakarta.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override * the password for http digest authentication feature for the request. *

* Example: *

     * Response response = client.target("http://localhost:8080/rest/joe/orders").request()
     *      .property(HTTP_AUTHENTICATION_DIGEST_USERNAME, "joe")
     *      .property(HTTP_AUTHENTICATION_DIGEST_PASSWORD, "p1swd745").get();
     * 
*

* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property * (as shown in the example). The property pair influence only credentials used during digest authentication. *

* The value must be instance of {@link String} or {@code byte} array ({@code byte[]}). *

*

* The name of the configuration property is {@value}. *

*/ public static final String HTTP_AUTHENTICATION_DIGEST_PASSWORD = "jersey.config.client.http.auth.digest.password"; /** * Create the builder of the http authentication feature working in basic authentication mode. The builder * can build preemptive and non-preemptive basic authentication features. * * @return Basic http authentication builder. */ public static BasicBuilder basicBuilder() { return new BuilderImpl(Mode.BASIC_PREEMPTIVE); } /** * Create the http authentication feature in basic preemptive authentication mode initialized with credentials. * * @param username Username. * @param password Password as {@code byte array}. * @return Http authentication feature configured in basic mode. */ public static HttpAuthenticationFeature basic(String username, byte[] password) { return build(Mode.BASIC_PREEMPTIVE, username, password); } /** * Create the http authentication feature in basic preemptive authentication mode initialized with credentials. * * @param username Username. * @param password Password as {@link String}. * @return Http authentication feature configured in basic mode. */ public static HttpAuthenticationFeature basic(String username, String password) { return build(Mode.BASIC_PREEMPTIVE, username, password); } /** * Create the http authentication feature in digest authentication mode initialized without default * credentials. Credentials will have to be supplied using request properties for each request. * * @return Http authentication feature configured in digest mode. */ public static HttpAuthenticationFeature digest() { return build(Mode.DIGEST); } /** * Create the http authentication feature in digest authentication mode initialized with credentials. * * @param username Username. * @param password Password as {@code byte array}. * @return Http authentication feature configured in digest mode. */ public static HttpAuthenticationFeature digest(String username, byte[] password) { return build(Mode.DIGEST, username, password); } /** * Create the http authentication feature in digest authentication mode initialized with credentials. * * @param username Username. * @param password Password as {@link String}. * @return Http authentication feature configured in digest mode. */ public static HttpAuthenticationFeature digest(String username, String password) { return build(Mode.DIGEST, username, password); } /** * Create the builder that builds http authentication feature in combined mode supporting both, * basic and digest authentication. * * @return Universal builder. */ public static UniversalBuilder universalBuilder() { return new BuilderImpl(Mode.UNIVERSAL); } /** * Create the http authentication feature in combined mode supporting both, * basic and digest authentication. * * @param username Username. * @param password Password as {@code byte array}. * @return Http authentication feature configured in digest mode. */ public static HttpAuthenticationFeature universal(String username, byte[] password) { return build(Mode.UNIVERSAL, username, password); } /** * Create the http authentication feature in combined mode supporting both, * basic and digest authentication. * * @param username Username. * @param password Password as {@link String}. * @return Http authentication feature configured in digest mode. */ public static HttpAuthenticationFeature universal(String username, String password) { return build(Mode.UNIVERSAL, username, password); } private static HttpAuthenticationFeature build(Mode mode) { return new BuilderImpl(mode).build(); } private static HttpAuthenticationFeature build(Mode mode, String username, byte[] password) { return new BuilderImpl(mode).credentials(username, password).build(); } private static HttpAuthenticationFeature build(Mode mode, String username, String password) { return new BuilderImpl(mode).credentials(username, password).build(); } private final Mode mode; private final HttpAuthenticationFilter.Credentials basicCredentials; private final HttpAuthenticationFilter.Credentials digestCredentials; private HttpAuthenticationFeature(Mode mode, HttpAuthenticationFilter.Credentials basicCredentials, HttpAuthenticationFilter.Credentials digestCredentials) { this.mode = mode; this.basicCredentials = basicCredentials; this.digestCredentials = digestCredentials; } @Override public boolean configure(FeatureContext context) { context.register(new HttpAuthenticationFilter(mode, basicCredentials, digestCredentials, context.getConfiguration())); return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy