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
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * http://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.jersey.client.authentication;

import javax.ws.rs.core.Feature;
import javax.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. *
  • *
  • 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 javax.ws.rs.client.Client}, * {@link javax.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 javax.ws.rs.client.ClientRequestContext client request} * using {@link javax.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 javax.ws.rs.client.ClientRequestContext client request} * using {@link javax.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 javax.ws.rs.client.ClientRequestContext client request} * using {@link javax.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 javax.ws.rs.client.ClientRequestContext client request} * using {@link javax.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 javax.ws.rs.client.ClientRequestContext client request} * using {@link javax.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 javax.ws.rs.client.ClientRequestContext client request} * using {@link javax.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