View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.auth;
28  
29  import java.security.Principal;
30  
31  import org.apache.hc.core5.http.HttpHost;
32  import org.apache.hc.core5.http.HttpRequest;
33  import org.apache.hc.core5.http.protocol.HttpContext;
34  
35  /**
36   * This interface represents an abstract challenge-response oriented authentication scheme.
37   * <p>
38   * Authentication schemes can be either request or connection based. The former are
39   * expected to provide an authorization response with each request message while the latter
40   * is executed only once and applies to the underlying connection for its entire life span.
41   * Care must be taken when re-using connections authorized through a connection based
42   * authentication scheme and they may carry a particular security context and be authorized
43   * for a particular user identity. It is important that such schemes always provide
44   * the user identity they represent through the {@link #getPrincipal()} method.
45   * </p>
46   * <p>
47   * Authentication scheme are expected to transition through a series of standard phases or
48   * states.
49   * </p>
50   * <p>
51   * Authentication scheme starts off its life cycle with no context and no specific state.
52   * </p>
53   * <p>
54   * The {@link #processChallenge(AuthChallenge, HttpContext)} method is called  to
55   * process an authentication challenge received either from the target server or a proxy.
56   * The authentication scheme transitions to CHALLENGED state and is expected to validate
57   * the token passed to it as a parameter and initialize its internal state based on
58   * challenge details. Standard authentication schemes are expected to provide a realm
59   * attribute in the challenge. {@link #getRealm()} can be called to obtain an identifier
60   * of the realm that requires authorization.
61   * </p>
62   * <p>
63   * Once the challenge has been fully processed the {@link #isResponseReady(HttpHost,
64   * CredentialsProvider, HttpContext)} method to determine whether the scheme is capable of
65   * generating a authorization response based on its current state and it holds user credentials
66   * required to do so. If this method returns {@code false} the authentication is considered
67   * to be in FAILED state and no authorization response. Otherwise the scheme is considered
68   * to be in RESPONSE_READY state.
69   * </p>
70   * <p>
71   * Once the scheme is ready to respond to the challenge the {@link #generateAuthResponse(
72   * HttpHost, HttpRequest, HttpContext)} method to generate a response token, which will
73   * be sent to the opposite endpoint in the subsequent request message.
74   * </p>
75   * <p>
76   * Certain non-standard schemes may involve multiple challenge / response exchanges to
77   * fully establish a shared context and complete the authentication process. Authentication
78   * schemes are required to return {@code true} {@link #isChallengeComplete()} once the
79   * handshake is considered complete.
80   * </p>
81   * <p>
82   * The authentication scheme is considered successfully completed and in SUCCESS state
83   * if the opposite endpoint accepts the request message containing the authorization
84   * response and responds with a message indicating no authentication failure .
85   * If the opposite endpoint sends status code 401 or 407 in response to a request message
86   * containing the terminal authorization response, the scheme is considered unsuccessful
87   * and in FAILED state.
88   * </p>
89   *
90   * @since 4.0
91   */
92  public interface AuthScheme {
93  
94      /**
95       * Returns textual designation of the given authentication scheme.
96       *
97       * @return the name of the given authentication scheme
98       */
99      String getName();
100 
101     /**
102      * Determines if the authentication scheme is expected to provide an authorization response
103      * on a per connection basis instead of the standard per request basis
104      *
105      * @return {@code true} if the scheme is connection based, {@code false}
106      * if the scheme is request based.
107      */
108     boolean isConnectionBased();
109 
110     /**
111      * Processes the given auth challenge. Some authentication schemes may involve multiple
112      * challenge-response exchanges. Such schemes must be able to maintain internal state
113      * when dealing with sequential challenges
114      *
115      * @param authChallenge the auth challenge
116      * @param context HTTP context
117      * @throws MalformedChallengeException in case the auth challenge is incomplete,
118      * malformed or otherwise invalid.
119      * @since 5.0
120      */
121     void processChallenge(
122             AuthChallenge authChallenge,
123             HttpContext context) throws MalformedChallengeException;
124 
125     /**
126      * Authentication process may involve a series of challenge-response exchanges.
127      * This method tests if the authorization process has been fully completed (either
128      * successfully or unsuccessfully), that is, all the required authorization
129      * challenges have been processed in their entirety.
130      *
131      * @return {@code true} if the authentication process has been completed,
132      * {@code false} otherwise.
133      *
134      * @since 5.0
135      */
136     boolean isChallengeComplete();
137 
138     /**
139      * Returns authentication realm. If the concept of an authentication
140      * realm is not applicable to the given authentication scheme, returns
141      * {@code null}.
142      *
143      * @return the authentication realm
144      */
145     String getRealm();
146 
147     /**
148      * Determines whether or not an authorization response can be generated based on
149      * the actual authentication state. Generally the outcome of this method will depend
150      * upon availability of user credentials necessary to produce an authorization
151      * response.
152      *
153      * @param credentialsProvider The credentials to be used for authentication
154      * @param context HTTP context
155      * @throws AuthenticationException if authorization string cannot
156      *   be generated due to an authentication failure
157      *
158      * @return {@code true} if an authorization response can be generated and
159      * the authentication handshake can proceed, {@code false} otherwise.
160      *
161      * @since 5.0
162      */
163     boolean isResponseReady(
164             HttpHost host,
165             CredentialsProvider credentialsProvider,
166             HttpContext context) throws AuthenticationException;
167 
168     /**
169      * Returns {@link Principal} whose credentials are used to generate
170      * an authentication response. Connection based schemes are required
171      * to return a user {@link Principal} if authorization applies to
172      * for the entire life span of connection.
173      * @return user principal
174      *
175      * @see #isConnectionBased()
176      *
177      * @since 5.0
178      */
179     Principal getPrincipal();
180 
181     /**
182      * Generates an authorization response based on the current state. Some authentication
183      * schemes may need to load user credentials required to generate an authorization
184      * response from a {@link CredentialsProvider} prior to this method call.
185      *
186      * @param request The request being authenticated
187      * @param context HTTP context
188      * @throws AuthenticationException if authorization string cannot
189      *   be generated due to an authentication failure
190      *
191      * @return authorization header
192      *
193      * @see #isResponseReady(HttpHost, CredentialsProvider, HttpContext)
194      *
195      * @since 5.0
196      */
197     String generateAuthResponse(
198             HttpHost host,
199             HttpRequest request,
200             HttpContext context) throws AuthenticationException;
201 
202 }