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 }