|
24 | 24 | import java.io.UnsupportedEncodingException;
|
25 | 25 | import java.net.InetAddress;
|
26 | 26 | import java.net.InetSocketAddress;
|
| 27 | +import java.net.MalformedURLException; |
27 | 28 | import java.net.URI;
|
28 | 29 | import java.net.URISyntaxException;
|
29 | 30 | import java.net.URL;
|
|
62 | 63 | import org.apache.http.auth.AuthState;
|
63 | 64 | import org.apache.http.auth.Credentials;
|
64 | 65 | import org.apache.http.auth.NTCredentials;
|
| 66 | +import org.apache.http.auth.UsernamePasswordCredentials; |
65 | 67 | import org.apache.http.client.AuthCache;
|
66 | 68 | import org.apache.http.client.AuthenticationStrategy;
|
67 | 69 | import org.apache.http.client.CredentialsProvider;
|
@@ -205,6 +207,80 @@ public class HTTPHC4Impl extends HTTPHCAbstractImpl {
|
205 | 207 |
|
206 | 208 | private static final InputStreamFactory BROTLI = BrotliInputStream::new;
|
207 | 209 |
|
| 210 | + private static final class ManagedCredentialsProvider implements CredentialsProvider { |
| 211 | + private AuthManager authManager; |
| 212 | + private Credentials proxyCredentials; |
| 213 | + private AuthScope proxyAuthScope; |
| 214 | + |
| 215 | + public ManagedCredentialsProvider(AuthManager authManager, AuthScope proxyAuthScope, Credentials proxyCredentials) { |
| 216 | + this.authManager = authManager; |
| 217 | + this.proxyAuthScope = proxyAuthScope; |
| 218 | + this.proxyCredentials = proxyCredentials; |
| 219 | + } |
| 220 | + |
| 221 | + @Override |
| 222 | + public void setCredentials(AuthScope authscope, Credentials credentials) { |
| 223 | + log.debug("Store creds {} for {}", credentials, authscope); |
| 224 | + } |
| 225 | + |
| 226 | + @Override |
| 227 | + public Credentials getCredentials(AuthScope authScope) { |
| 228 | + log.info("Get creds for {}", authScope); |
| 229 | + if (this.proxyAuthScope != null && authScope.equals(proxyAuthScope)) { |
| 230 | + return proxyCredentials; |
| 231 | + } |
| 232 | + final Authorization authorization = getAuthorizationForAuthScope(authScope); |
| 233 | + if (authorization == null) { |
| 234 | + return null; |
| 235 | + } |
| 236 | + return new UsernamePasswordCredentials(authorization.getUser(), authorization.getPass()); |
| 237 | + } |
| 238 | + |
| 239 | + /** |
| 240 | + * Find the Authorization for the given AuthScope. We can't ask the AuthManager |
| 241 | + * by the URL, as we didn't get the scheme or path of the URL. Therefore we do a |
| 242 | + * best guess on the information we have |
| 243 | + * |
| 244 | + * @param authScope information which destination we want to get credentials for |
| 245 | + * @return matching authorization information entry from the AuthManager |
| 246 | + */ |
| 247 | + private Authorization getAuthorizationForAuthScope(AuthScope authScope) { |
| 248 | + if (authScope == null) { |
| 249 | + return null; |
| 250 | + } |
| 251 | + for (JMeterProperty authProp : authManager.getAuthObjects()) { |
| 252 | + Object authObject = authProp.getObjectValue(); |
| 253 | + if (authObject instanceof Authorization) { |
| 254 | + Authorization auth = (Authorization) authObject; |
| 255 | + if (!authScope.getRealm().equals(auth.getRealm())) { |
| 256 | + continue; |
| 257 | + } |
| 258 | + try { |
| 259 | + URL authUrl = new URL(auth.getURL()); |
| 260 | + if (authUrl.getHost().equals(authScope.getHost()) && getPort(authUrl) == authScope.getPort()) { |
| 261 | + return auth; |
| 262 | + } |
| 263 | + } catch (MalformedURLException e) { |
| 264 | + log.debug("Invalid URL {} in authManager", auth.getURL()); |
| 265 | + } |
| 266 | + } |
| 267 | + } |
| 268 | + return null; |
| 269 | + } |
| 270 | + |
| 271 | + private int getPort(URL url) { |
| 272 | + if (url.getPort() == -1) { |
| 273 | + return url.getProtocol().equals("https") ? 443 : 80; |
| 274 | + } |
| 275 | + return url.getPort(); |
| 276 | + } |
| 277 | + |
| 278 | + @Override |
| 279 | + public void clear() { |
| 280 | + log.debug("clear creds"); |
| 281 | + } |
| 282 | + } |
| 283 | + |
208 | 284 | private static final class PreemptiveAuthRequestInterceptor implements HttpRequestInterceptor {
|
209 | 285 | @Override
|
210 | 286 | public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
|
@@ -1055,21 +1131,27 @@ private MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectio
|
1055 | 1131 | }
|
1056 | 1132 |
|
1057 | 1133 | // Set up proxy details
|
| 1134 | + AuthScope proxyAuthScope = null; |
| 1135 | + NTCredentials proxyCredentials = null; |
1058 | 1136 | if (key.hasProxy) {
|
1059 | 1137 | HttpHost proxy = new HttpHost(key.proxyHost, key.proxyPort, key.proxyScheme);
|
1060 | 1138 | builder.setProxy(proxy);
|
1061 | 1139 |
|
1062 | 1140 | CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
1063 | 1141 | if (!key.proxyUser.isEmpty()) {
|
| 1142 | + proxyAuthScope = new AuthScope(key.proxyHost, key.proxyPort); |
| 1143 | + proxyCredentials = new NTCredentials(key.proxyUser, key.proxyPass, LOCALHOST, PROXY_DOMAIN); |
1064 | 1144 | credsProvider.setCredentials(
|
1065 |
| - new AuthScope(key.proxyHost, key.proxyPort), |
1066 |
| - new NTCredentials(key.proxyUser, key.proxyPass, LOCALHOST, PROXY_DOMAIN)); |
| 1145 | + proxyAuthScope, |
| 1146 | + proxyCredentials); |
1067 | 1147 | }
|
1068 | 1148 | builder.setDefaultCredentialsProvider(credsProvider);
|
1069 | 1149 | }
|
1070 | 1150 | builder.disableContentCompression().addInterceptorLast(RESPONSE_CONTENT_ENCODING);
|
1071 | 1151 | if(BASIC_AUTH_PREEMPTIVE) {
|
1072 | 1152 | builder.addInterceptorFirst(PREEMPTIVE_AUTH_INTERCEPTOR);
|
| 1153 | + } else { |
| 1154 | + builder.setDefaultCredentialsProvider(new ManagedCredentialsProvider(getAuthManager(), proxyAuthScope, proxyCredentials)); |
1073 | 1155 | }
|
1074 | 1156 | httpClient = builder.build();
|
1075 | 1157 | if (log.isDebugEnabled()) {
|
|
0 commit comments