NTLM scheme deprecated and disabled by default

This commit is contained in:
Oleg Kalnichevski 2023-05-07 15:39:08 +02:00
parent 8aa4fbc8de
commit 83c6079e65
40 changed files with 72 additions and 1238 deletions

View File

@ -30,7 +30,6 @@ The JAR packages can be found in the target folders of their respective modules
httpclient5/target/httpclient5-<VERSION>.jar httpclient5/target/httpclient5-<VERSION>.jar
httpclient5-cache/target/httpclient5-cache-<VERSION>.jar httpclient5-cache/target/httpclient5-cache-<VERSION>.jar
httpclient5-fluent/target/httpclient5-fluent-<VERSION>.jar httpclient5-fluent/target/httpclient5-fluent-<VERSION>.jar
httpclient5-win/target/httpclient5-win-<VERSION>.jar
httpclient5-osgi/target/org.apache.httpcomponents.httpclient_<VERSION>.jar httpclient5-osgi/target/org.apache.httpcomponents.httpclient_<VERSION>.jar
where <VERSION> is the release version where <VERSION> is the release version

View File

@ -52,6 +52,7 @@ import org.apache.hc.core5.http.message.StatusLine;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation")
public class TestByteArrayCacheEntrySerializer { public class TestByteArrayCacheEntrySerializer {
private ByteArrayCacheEntrySerializer impl; private ByteArrayCacheEntrySerializer impl;

View File

@ -33,7 +33,6 @@ import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.AuthScope; import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.Credentials; import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.auth.CredentialsStore; import org.apache.hc.client5.http.auth.CredentialsStore;
import org.apache.hc.client5.http.auth.NTCredentials;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.cookie.CookieStore; import org.apache.hc.client5.http.cookie.CookieStore;
@ -186,10 +185,14 @@ public class Executor {
return auth(host, new UsernamePasswordCredentials(username, password)); return auth(host, new UsernamePasswordCredentials(username, password));
} }
/**
* @deprecated Use {@link #auth(HttpHost, String, char[])}.
*/
@Deprecated
public Executor auth(final HttpHost host, public Executor auth(final HttpHost host,
final String username, final char[] password, final String username, final char[] password,
final String workstation, final String domain) { final String workstation, final String domain) {
return auth(host, new NTCredentials(username, password, workstation, domain)); return auth(host, new org.apache.hc.client5.http.auth.NTCredentials(username, password, workstation, domain));
} }
public Executor clearAuth() { public Executor clearAuth() {

View File

@ -77,11 +77,6 @@
<artifactId>httpclient5-fluent</artifactId> <artifactId>httpclient5-fluent</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5-win</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId> <artifactId>junit-jupiter-params</artifactId>

View File

@ -1,48 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.impl.win;
import com.sun.jna.platform.win32.Sspi;
import com.sun.jna.platform.win32.Win32Exception;
import com.sun.jna.platform.win32.WinError;
public final class WindowsNegotiateSchemeGetTokenFail extends WindowsNegotiateScheme {
public WindowsNegotiateSchemeGetTokenFail(final String schemeName, final String servicePrincipalName) {
super(schemeName, servicePrincipalName);
}
@Override
String getToken(final Sspi.CtxtHandle continueCtx, final Sspi.SecBufferDesc continueToken, final String targetName) {
dispose();
/* We will rather throw SEC_E_TARGET_UNKNOWN because SEC_E_DOWNGRADE_DETECTED is not
* available on Windows XP and this unit test always fails.
*/
throw new Win32Exception(WinError.SEC_E_TARGET_UNKNOWN);
}
}

View File

@ -1,261 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.testing.sync;
import java.io.IOException;
import java.util.function.Consumer;
import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.auth.NTCredentials;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.testing.classic.ClassicTestServer;
import org.apache.hc.core5.util.Timeout;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/**
* Unit tests for some of the NTLM auth functionality..
*/
public class TestClientAuthenticationFakeNTLM {
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
@RegisterExtension
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
public ClassicTestServer startServer() throws IOException {
return testResources.startServer(null, null, null);
}
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) {
return testResources.startClient(clientCustomizer);
}
public CloseableHttpClient startClient() {
return testResources.startClient(builder -> {});
}
public HttpHost targetHost() {
return testResources.targetHost();
}
static class NtlmResponseHandler implements HttpRequestHandler {
@Override
public void handle(
final ClassicHttpRequest request,
final ClassicHttpResponse response,
final HttpContext context) throws HttpException, IOException {
response.setCode(HttpStatus.SC_UNAUTHORIZED);
response.setHeader("Connection", "Keep-Alive");
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.NTLM);
}
}
@Test
public void testNTLMAuthenticationFailure() throws Exception {
final ClassicTestServer server = startServer();
server.registerHandler("*", new NtlmResponseHandler());
final HttpHost target = targetHost();
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
.build();
final CloseableHttpClient client = startClient(builder -> builder
.setDefaultCredentialsProvider(credsProvider)
);
final HttpContext context = HttpClientContext.create();
final HttpGet httpget = new HttpGet("/");
client.execute(target, httpget, context, response -> {
EntityUtils.consume(response.getEntity());
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
return null;
});
}
static class NtlmType2MessageResponseHandler implements HttpRequestHandler {
private final String authenticateHeaderValue;
public NtlmType2MessageResponseHandler(final String type2Message) {
this.authenticateHeaderValue = StandardAuthScheme.NTLM + " " + type2Message;
}
@Override
public void handle(
final ClassicHttpRequest request,
final ClassicHttpResponse response,
final HttpContext context) throws HttpException, IOException {
response.setCode(HttpStatus.SC_UNAUTHORIZED);
response.setHeader("Connection", "Keep-Alive");
if (!request.containsHeader(HttpHeaders.AUTHORIZATION)) {
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.NTLM);
} else {
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue);
}
}
}
@Test
public void testNTLMv1Type2Message() throws Exception {
final ClassicTestServer server = startServer();
server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
"AGUAcgB2AGUAcgA="));
final HttpHost target = targetHost();
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
.build();
final CloseableHttpClient client = startClient(builder -> builder
.setDefaultCredentialsProvider(credsProvider)
);
final HttpContext context = HttpClientContext.create();
final HttpGet httpget = new HttpGet("/");
client.execute(target, httpget, context, response -> {
EntityUtils.consume(response.getEntity());
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
return null;
});
}
@Test
public void testNTLMv2Type2Message() throws Exception {
final ClassicTestServer server = startServer();
server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
"AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" +
"AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA="));
final HttpHost target = targetHost();
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
.build();
final CloseableHttpClient client = startClient(builder -> builder
.setDefaultCredentialsProvider(credsProvider)
);
final HttpContext context = HttpClientContext.create();
final HttpGet httpget = new HttpGet("/");
client.execute(target, httpget, context, response -> {
EntityUtils.consume(response.getEntity());
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
return null;
});
}
static class NtlmType2MessageOnlyResponseHandler implements HttpRequestHandler {
private final String authenticateHeaderValue;
public NtlmType2MessageOnlyResponseHandler(final String type2Message) {
this.authenticateHeaderValue = StandardAuthScheme.NTLM + " " + type2Message;
}
@Override
public void handle(
final ClassicHttpRequest request,
final ClassicHttpResponse response,
final HttpContext context) throws HttpException, IOException {
response.setCode(HttpStatus.SC_UNAUTHORIZED);
response.setHeader("Connection", "Keep-Alive");
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue);
}
}
@Test
public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception {
final ClassicTestServer server = startServer();
server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
"AGUAcgB2AGUAcgA="));
final HttpHost target = targetHost();
final CloseableHttpClient client = startClient();
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(CredentialsProviderBuilder.create()
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
.build());
final HttpGet httpget = new HttpGet("/");
client.execute(target, httpget, context, response -> {
EntityUtils.consume(response.getEntity());
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
return null;
});
}
@Test
public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception {
final ClassicTestServer server = startServer();
server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
"AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
"ZXJ2ZXI="));
final HttpHost target = targetHost();
final CloseableHttpClient client = startClient();
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(CredentialsProviderBuilder.create()
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
.build());
final HttpGet httpget = new HttpGet("/");
client.execute(target, httpget, context, response -> {
EntityUtils.consume(response.getEntity());
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
return null;
});
}
}

View File

@ -125,6 +125,7 @@ public class TestSPNegoScheme {
} }
@SuppressWarnings("deprecation")
private static class UseJaasCredentials implements Credentials { private static class UseJaasCredentials implements Credentials {
@Override @Override

View File

@ -1,94 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.testing.sync;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.win.WinHttpClients;
import org.apache.hc.client5.http.impl.win.WindowsNegotiateSchemeGetTokenFail;
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.Registry;
import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.testing.classic.ClassicTestServer;
import org.apache.hc.core5.util.Timeout;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/**
* Unit tests for Windows negotiate authentication.
*/
public class TestWindowsNegotiateScheme {
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
@RegisterExtension
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
@Test // this timeout (in ms) needs to be extended if you're actively debugging the code
@org.junit.jupiter.api.Timeout(value = 30000, unit = MILLISECONDS)
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
final ClassicTestServer server = testResources.startServer(null, null, null);
server.registerHandler("/", (request, response, context) -> {
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
response.setCode(HttpStatus.SC_UNAUTHORIZED);
});
final HttpHost target = testResources.targetHost();
Assumptions.assumeTrue(WinHttpClients.isWinAuthAvailable(), "Test can only be run on Windows");
// HTTPCLIENT-1545
// If a service principal name (SPN) from outside your Windows domain tree (e.g., HTTP/example.com) is used,
// InitializeSecurityContext will return SEC_E_DOWNGRADE_DETECTED (decimal: -2146892976, hex: 0x80090350).
// Because WindowsNegotiateScheme wasn't setting the completed state correctly when authentication fails,
// HttpClient goes into an infinite loop, constantly retrying the negotiate authentication to kingdom
// come. This error message, "The system detected a possible attempt to compromise security. Please ensure that
// you can contact the server that authenticated you." is associated with SEC_E_DOWNGRADE_DETECTED.
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
.register(StandardAuthScheme.SPNEGO, context -> new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com")).build();
final CloseableHttpClient client = testResources.startClient(builder -> builder
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
);
final HttpGet httpGet = new HttpGet("/");
client.execute(target, httpGet, response -> {
EntityUtils.consume(response.getEntity());
return null;
});
}
}

View File

@ -1,107 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====================================================================
This software consists of voluntary contributions made by many
individuals on behalf of the Apache Software Foundation. For more
information on the Apache Software Foundation, please see
<http://www.apache.org />.
--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5-parent</artifactId>
<version>5.2.2-SNAPSHOT</version>
</parent>
<artifactId>httpclient5-win</artifactId>
<name>Apache HttpClient Windows features</name>
<description>Apache HttpClient Windows specific functionality</description>
<packaging>jar</packaging>
<properties>
<Automatic-Module-Name>org.apache.httpcomponents.client5.httpclient5.win</Automatic-Module-Name>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-migrationsupport</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<reporting>
<plugins>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<inherited>false</inherited>
<reportSets>
<reportSet>
<reports>
<report>index</report>
<report>dependencies</report>
<report>dependency-info</report>
<report>summary</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -1,70 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.examples.client.win;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.win.WinHttpClients;
import org.apache.hc.core5.http.io.entity.EntityUtils;
/**
* This example demonstrates how to create HttpClient pre-configured
* with support for integrated Windows authentication.
*/
public class ClientWinAuth {
public final static void main(String[] args) throws Exception {
if (!WinHttpClients.isWinAuthAvailable()) {
System.out.println("Integrated Win auth is not supported!!!");
}
CloseableHttpClient httpclient = WinHttpClients.createDefault();
// There is no need to provide user credentials
// HttpClient will attempt to access current user security context through
// Windows platform specific methods via JNI.
try {
HttpGet httpget = new HttpGet("http://winhost/");
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
CloseableHttpResponse response = httpclient.execute(httpget);
try {
System.out.println("----------------------------------------");
System.out.println(response.getCode() + " " + response.getReasonPhrase());
EntityUtils.consume(response.getEntity());
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}

View File

@ -1,99 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.impl.win;
import java.util.Locale;
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory;
import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.config.Registry;
import org.apache.hc.core5.http.config.RegistryBuilder;
/**
* Factory methods for {@link org.apache.hc.client5.http.impl.classic.CloseableHttpClient} instances configured to use integrated
* Windows authentication by default.
*
* @since 4.4
*/
public class WinHttpClients {
private WinHttpClients() {
super();
}
public static boolean isWinAuthAvailable() {
String os = System.getProperty("os.name");
os = os != null ? os.toLowerCase(Locale.ROOT) : null;
return os != null && os.contains("windows");
}
private static HttpClientBuilder createBuilder() {
if (isWinAuthAvailable()) {
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, WindowsNTLMSchemeFactory.DEFAULT)
.register(StandardAuthScheme.SPNEGO, WindowsNegotiateSchemeFactory.DEFAULT)
.build();
return HttpClientBuilder.create()
.setDefaultAuthSchemeRegistry(authSchemeRegistry);
}
return HttpClientBuilder.create();
}
/**
* Creates builder object for construction of custom
* {@link CloseableHttpClient} instances.
*/
public static HttpClientBuilder custom() {
return createBuilder();
}
/**
* Creates {@link CloseableHttpClient} instance with default
* configuration.
*/
public static CloseableHttpClient createDefault() {
return createBuilder().build();
}
/**
* Creates {@link CloseableHttpClient} instance with default
* configuration based on system properties.
*/
public static CloseableHttpClient createSystem() {
return createBuilder().useSystemProperties().build();
}
}

View File

@ -1,68 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.impl.win;
import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.protocol.HttpContext;
/**
* {@link AuthSchemeFactory} implementation that creates and initializes
* {@link WindowsNegotiateScheme} using JNA to implement NTLM
*
* @since 4.4
*/
@Contract(threading = ThreadingBehavior.STATELESS)
@Experimental
public class WindowsNTLMSchemeFactory implements AuthSchemeFactory {
/**
* Singleton instance with a null name.
*/
public static final WindowsNTLMSchemeFactory DEFAULT = new WindowsNTLMSchemeFactory(null);
private final String servicePrincipalName;
public WindowsNTLMSchemeFactory(final String servicePrincipalName) {
super();
this.servicePrincipalName = servicePrincipalName;
}
@Override
public AuthScheme create(final HttpContext context) {
return new WindowsNegotiateScheme(StandardAuthScheme.NTLM, servicePrincipalName);
}
}

View File

@ -1,294 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.impl.win;
import java.security.Principal;
import org.apache.hc.client5.http.utils.Base64;
import org.apache.hc.client5.http.RouteInfo;
import org.apache.hc.client5.http.auth.AuthChallenge;
import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.client5.http.auth.AuthenticationException;
import org.apache.hc.client5.http.auth.BasicUserPrincipal;
import org.apache.hc.client5.http.auth.ChallengeType;
import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.auth.MalformedChallengeException;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIAuthority;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.platform.win32.Secur32;
import com.sun.jna.platform.win32.Secur32Util;
import com.sun.jna.platform.win32.Sspi;
import com.sun.jna.platform.win32.Sspi.CredHandle;
import com.sun.jna.platform.win32.Sspi.CtxtHandle;
import com.sun.jna.platform.win32.Sspi.SecBufferDesc;
import com.sun.jna.platform.win32.Sspi.TimeStamp;
import com.sun.jna.platform.win32.SspiUtil.ManagedSecBufferDesc;
import com.sun.jna.platform.win32.Win32Exception;
import com.sun.jna.platform.win32.WinError;
import com.sun.jna.ptr.IntByReference;
/**
* Auth scheme that makes use of JNA to implement Negotiate and NTLM on Windows Platforms.
* <p>
* This will delegate negotiation to the windows machine.
* </p>
*
* @since 4.4
*/
@Experimental
public class WindowsNegotiateScheme implements AuthScheme {
private static final Logger LOG = LoggerFactory.getLogger(WindowsNegotiateScheme.class);
// NTLM or Negotiate
private final String schemeName;
private final String servicePrincipalName;
private ChallengeType challengeType;
private String challenge;
private CredHandle clientCred;
private CtxtHandle sspiContext;
private boolean continueNeeded;
WindowsNegotiateScheme(final String schemeName, final String servicePrincipalName) {
super();
this.schemeName = (schemeName == null) ? StandardAuthScheme.SPNEGO : schemeName;
this.continueNeeded = true;
this.servicePrincipalName = servicePrincipalName;
if (LOG.isDebugEnabled()) {
LOG.debug("Created WindowsNegotiateScheme using {}", this.schemeName);
}
}
public void dispose() {
if (clientCred != null && !clientCred.isNull()) {
final int rc = Secur32.INSTANCE.FreeCredentialsHandle(clientCred);
if (WinError.SEC_E_OK != rc) {
throw new Win32Exception(rc);
}
}
if (sspiContext != null && !sspiContext.isNull()) {
final int rc = Secur32.INSTANCE.DeleteSecurityContext(sspiContext);
if (WinError.SEC_E_OK != rc) {
throw new Win32Exception(rc);
}
}
continueNeeded = true; // waiting
clientCred = null;
sspiContext = null;
}
@Override
public String getName() {
return schemeName;
}
@Override
public boolean isConnectionBased() {
return true;
}
@Override
public String getRealm() {
return null;
}
@Override
public void processChallenge(
final AuthChallenge authChallenge,
final HttpContext context) throws MalformedChallengeException {
Args.notNull(authChallenge, "AuthChallenge");
challengeType = authChallenge.getChallengeType();
challenge = authChallenge.getValue();
if (TextUtils.isBlank(challenge)) {
if (clientCred != null) {
dispose(); // run cleanup first before throwing an exception otherwise can leak OS resources
if (continueNeeded) {
throw new IllegalStateException("Unexpected token");
}
}
}
}
@Override
public boolean isResponseReady(
final HttpHost host,
final CredentialsProvider credentialsProvider,
final HttpContext context) throws AuthenticationException {
return true;
}
/**
* Get the SAM-compatible username of the currently logged-on user.
*
* @return String.
*/
public static String getCurrentUsername() {
return Secur32Util.getUserNameEx(Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible);
}
@Override
public Principal getPrincipal() {
return new BasicUserPrincipal(getCurrentUsername());
}
@Override
public String generateAuthResponse(
final HttpHost host,
final HttpRequest request,
final HttpContext context) throws AuthenticationException {
final HttpClientContext clientContext = HttpClientContext.adapt(context);
final String response;
if (clientCred == null) {
// client credentials handle
try {
final String username = getCurrentUsername();
final TimeStamp lifetime = new TimeStamp();
clientCred = new CredHandle();
final int rc = Secur32.INSTANCE.AcquireCredentialsHandle(username,
schemeName, Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null,
clientCred, lifetime);
if (WinError.SEC_E_OK != rc) {
throw new Win32Exception(rc);
}
final String targetName = getServicePrincipalName(request, clientContext);
response = getToken(null, null, targetName);
} catch (final RuntimeException ex) {
failAuthCleanup();
if (ex instanceof Win32Exception) {
throw new AuthenticationException("Authentication Failed", ex);
}
throw ex;
}
} else if (challenge == null || challenge.isEmpty()) {
failAuthCleanup();
throw new AuthenticationException("Authentication Failed");
} else {
try {
final byte[] continueTokenBytes = Base64.decodeBase64(challenge);
final SecBufferDesc continueTokenBuffer = new ManagedSecBufferDesc(
Sspi.SECBUFFER_TOKEN, continueTokenBytes);
final String targetName = getServicePrincipalName(request, clientContext);
response = getToken(this.sspiContext, continueTokenBuffer, targetName);
} catch (final RuntimeException ex) {
failAuthCleanup();
if (ex instanceof Win32Exception) {
throw new AuthenticationException("Authentication Failed", ex);
}
throw ex;
}
}
return schemeName + " " + response;
}
private void failAuthCleanup() {
dispose();
this.continueNeeded = false;
}
// Per RFC4559, the Service Principal Name should HTTP/<hostname>. However, <hostname>
// can just be the host or the fully qualified name (e.g., see "Kerberos SPN generation"
// at http://www.chromium.org/developers/design-documents/http-authentication). Here,
// I've chosen to use the host that has been provided in HttpHost so that I don't incur
// any additional DNS lookup cost.
private String getServicePrincipalName(final HttpRequest request, final HttpClientContext clientContext) {
String spn = null;
if (this.servicePrincipalName != null) {
spn = this.servicePrincipalName;
} else if (challengeType == ChallengeType.PROXY) {
final RouteInfo route = clientContext.getHttpRoute();
if (route != null) {
spn = "HTTP/" + route.getProxyHost().getHostName();
}
} else {
final URIAuthority authority = request.getAuthority();
if (authority != null) {
spn = "HTTP/" + authority.getHostName();
} else {
final RouteInfo route = clientContext.getHttpRoute();
if (route != null) {
spn = "HTTP/" + route.getTargetHost().getHostName();
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Using SPN: {}", spn);
}
return spn;
}
// See http://msdn.microsoft.com/en-us/library/windows/desktop/aa375506(v=vs.85).aspx
String getToken(
final CtxtHandle continueCtx,
final SecBufferDesc continueToken,
final String targetName) {
final IntByReference attr = new IntByReference();
final ManagedSecBufferDesc token = new ManagedSecBufferDesc(
Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
sspiContext = new CtxtHandle();
final int rc = Secur32.INSTANCE.InitializeSecurityContext(clientCred,
continueCtx, targetName, Sspi.ISC_REQ_DELEGATE | Sspi.ISC_REQ_MUTUAL_AUTH, 0,
Sspi.SECURITY_NATIVE_DREP, continueToken, 0, sspiContext, token,
attr, null);
switch (rc) {
case WinError.SEC_I_CONTINUE_NEEDED:
continueNeeded = true;
break;
case WinError.SEC_E_OK:
dispose(); // Don't keep the context
continueNeeded = false;
break;
default:
dispose();
throw new Win32Exception(rc);
}
return Base64.encodeBase64String(token.getBuffer(0).getBytes());
}
@Override
public boolean isChallengeComplete() {
return !continueNeeded;
}
}

View File

@ -1,67 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.impl.win;
import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.protocol.HttpContext;
/**
* {@link AuthSchemeFactory} implementation that creates and initializes
* {@link WindowsNegotiateScheme} using JNA to Negotiate credentials
*
* @since 4.4
*/
@Contract(threading = ThreadingBehavior.STATELESS)
@Experimental
public class WindowsNegotiateSchemeFactory implements AuthSchemeFactory {
/**
* Singleton instance with a null name.
*/
public static final WindowsNegotiateSchemeFactory DEFAULT = new WindowsNegotiateSchemeFactory(null);
private final String servicePrincipalName;
public WindowsNegotiateSchemeFactory(final String servicePrincipalName) {
super();
this.servicePrincipalName = servicePrincipalName;
}
@Override
public AuthScheme create(final HttpContext context) {
return new WindowsNegotiateScheme(StandardAuthScheme.SPNEGO, servicePrincipalName);
}
}

View File

@ -1,35 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
/**
* Auth scheme that makes use of JNA to implement Negotiate and NTLM on Windows Platforms.
* <p>
* Please note this class is considered experimental and may be discontinued or removed
* in the future.
* </p>
*/
package org.apache.hc.client5.http.impl.win;

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Configuration status="WARN" name="XMLConfigTest">
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%d %-5level [%t][%logger]%notEmpty{[%markerSimpleName]} %msg%n%xThrowable" />
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>

View File

@ -43,7 +43,14 @@ import org.apache.hc.core5.util.LangUtils;
* Windows specific attributes such as name of the domain the user belongs to. * Windows specific attributes such as name of the domain the user belongs to.
* *
* @since 4.0 * @since 4.0
*
* @deprecated Do not use. the NTLM authentication scheme is no longer supported.
* Consider using Basic or Bearer authentication with TLS instead.
*
* @see UsernamePasswordCredentials
* @see BearerToken
*/ */
@Deprecated
@Contract(threading = ThreadingBehavior.IMMUTABLE) @Contract(threading = ThreadingBehavior.IMMUTABLE)
public class NTCredentials implements Credentials, Serializable { public class NTCredentials implements Credentials, Serializable {
@ -69,9 +76,7 @@ public class NTCredentials implements Credentials, Serializable {
* @param workstation The workstation the authentication request is originating from. * @param workstation The workstation the authentication request is originating from.
* Essentially, the computer name for this machine. * Essentially, the computer name for this machine.
* @param domain The domain to authenticate within. * @param domain The domain to authenticate within.
* @deprecated (5.3) Use {@link #NTCredentials(char[], String, String, String)}
*/ */
@Deprecated
public NTCredentials( public NTCredentials(
final String userName, final String userName,
final char[] password, final char[] password,
@ -89,9 +94,7 @@ public class NTCredentials implements Credentials, Serializable {
* Essentially, the computer name for this machine. * Essentially, the computer name for this machine.
* @param domain The domain to authenticate within. * @param domain The domain to authenticate within.
* @param netbiosDomain The netbios version of the domain name. * @param netbiosDomain The netbios version of the domain name.
@deprecated (5.3) Use {@link #NTCredentials(char[], String, String, String)}
*/ */
@Deprecated
public NTCredentials( public NTCredentials(
final String userName, final String userName,
final char[] password, final char[] password,
@ -114,7 +117,6 @@ public class NTCredentials implements Credentials, Serializable {
* This constructor creates a new instance of NTCredentials, determining the workstation name at runtime * This constructor creates a new instance of NTCredentials, determining the workstation name at runtime
* using the {@link #getWorkstationName()} method. The workstation name will be converted to uppercase * using the {@link #getWorkstationName()} method. The workstation name will be converted to uppercase
* using the {@link java.util.Locale#ROOT} locale. * using the {@link java.util.Locale#ROOT} locale.
* @since 5.3
*/ */
public NTCredentials( public NTCredentials(
final char[] password, final char[] password,

View File

@ -57,7 +57,11 @@ public final class StandardAuthScheme {
/** /**
* The NTLM authentication scheme is a proprietary Microsoft Windows * The NTLM authentication scheme is a proprietary Microsoft Windows
* authentication protocol as defined in [MS-NLMP]. * authentication protocol as defined in [MS-NLMP].
*
* @deprecated Do not use. the NTLM authentication scheme is no longer supported.
* Consider using Basic or Bearer authentication with TLS instead.
*/ */
@Deprecated
public static final String NTLM = "NTLM"; public static final String NTLM = "NTLM";
/** /**

View File

@ -67,7 +67,6 @@ public class DefaultAuthenticationStrategy implements AuthenticationStrategy {
Collections.unmodifiableList(Arrays.asList( Collections.unmodifiableList(Arrays.asList(
StandardAuthScheme.SPNEGO, StandardAuthScheme.SPNEGO,
StandardAuthScheme.KERBEROS, StandardAuthScheme.KERBEROS,
StandardAuthScheme.NTLM,
StandardAuthScheme.BEARER, StandardAuthScheme.BEARER,
StandardAuthScheme.DIGEST, StandardAuthScheme.DIGEST,
StandardAuthScheme.BASIC)); StandardAuthScheme.BASIC));

View File

@ -61,7 +61,6 @@ import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory; import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory;
import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory; import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory; import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory;
import org.apache.hc.client5.http.impl.auth.NTLMSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory; import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SystemDefaultCredentialsProvider; import org.apache.hc.client5.http.impl.auth.SystemDefaultCredentialsProvider;
import org.apache.hc.client5.http.impl.nio.MultihomeConnectionInitiator; import org.apache.hc.client5.http.impl.nio.MultihomeConnectionInitiator;
@ -822,7 +821,6 @@ public class H2AsyncClientBuilder {
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE) .register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE) .register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE) .register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT) .register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT) .register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
.build(); .build();

View File

@ -67,7 +67,6 @@ import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory; import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory;
import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory; import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory; import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory;
import org.apache.hc.client5.http.impl.auth.NTLMSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory; import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SystemDefaultCredentialsProvider; import org.apache.hc.client5.http.impl.auth.SystemDefaultCredentialsProvider;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
@ -1009,7 +1008,6 @@ public class HttpAsyncClientBuilder {
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE) .register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE) .register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE) .register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT) .register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT) .register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
.build(); .build();

View File

@ -32,7 +32,10 @@ package org.apache.hc.client5.http.impl.auth;
* Type2 challenge. * Type2 challenge.
* *
* @since 4.0 * @since 4.0
*
* @deprecated Do not use. the NTLM authentication scheme is no longer supported
*/ */
@Deprecated
public interface NTLMEngine { public interface NTLMEngine {
/** /**

View File

@ -32,7 +32,10 @@ import org.apache.hc.client5.http.auth.AuthenticationException;
* Signals NTLM protocol failure. * Signals NTLM protocol failure.
* *
* @since 4.0 * @since 4.0
*
* @deprecated Do not use.
*/ */
@Deprecated
public class NTLMEngineException extends AuthenticationException { public class NTLMEngineException extends AuthenticationException {
private static final long serialVersionUID = 6027981323731768824L; private static final long serialVersionUID = 6027981323731768824L;

View File

@ -48,7 +48,10 @@ import org.apache.hc.client5.http.utils.ByteArrayBuilder;
* authentication protocol. * authentication protocol.
* *
* @since 4.1 * @since 4.1
*
* @deprecated Do not use.
*/ */
@Deprecated
final class NTLMEngineImpl implements NTLMEngine { final class NTLMEngineImpl implements NTLMEngine {
/** Unicode encoding */ /** Unicode encoding */

View File

@ -30,13 +30,12 @@ import java.security.Principal;
import org.apache.hc.client5.http.auth.AuthChallenge; import org.apache.hc.client5.http.auth.AuthChallenge;
import org.apache.hc.client5.http.auth.AuthScheme; import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.auth.AuthScope; import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.AuthenticationException; import org.apache.hc.client5.http.auth.AuthenticationException;
import org.apache.hc.client5.http.auth.Credentials; import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.auth.CredentialsProvider; import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.auth.MalformedChallengeException; import org.apache.hc.client5.http.auth.MalformedChallengeException;
import org.apache.hc.client5.http.auth.NTCredentials; import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest; import org.apache.hc.core5.http.HttpRequest;
@ -50,7 +49,14 @@ import org.slf4j.LoggerFactory;
* and optimized for Windows platforms. * and optimized for Windows platforms.
* *
* @since 4.0 * @since 4.0
*
* @deprecated Do not use. the NTLM authentication scheme is no longer supported.
* Consider using Basic or Bearer authentication with TLS instead.
*
* @see BasicScheme
* @see BearerScheme
*/ */
@Deprecated
public final class NTLMScheme implements AuthScheme { public final class NTLMScheme implements AuthScheme {
private static final Logger LOG = LoggerFactory.getLogger(NTLMScheme.class); private static final Logger LOG = LoggerFactory.getLogger(NTLMScheme.class);
@ -68,7 +74,7 @@ public final class NTLMScheme implements AuthScheme {
private State state; private State state;
private String challenge; private String challenge;
private NTCredentials credentials; private org.apache.hc.client5.http.auth.NTCredentials credentials;
public NTLMScheme(final NTLMEngine engine) { public NTLMScheme(final NTLMEngine engine) {
super(); super();
@ -134,8 +140,8 @@ public final class NTLMScheme implements AuthScheme {
final AuthScope authScope = new AuthScope(host, null, getName()); final AuthScope authScope = new AuthScope(host, null, getName());
final Credentials credentials = credentialsProvider.getCredentials( final Credentials credentials = credentialsProvider.getCredentials(
authScope, context); authScope, context);
if (credentials instanceof NTCredentials) { if (credentials instanceof org.apache.hc.client5.http.auth.NTCredentials) {
this.credentials = (NTCredentials) credentials; this.credentials = (org.apache.hc.client5.http.auth.NTCredentials) credentials;
return true; return true;
} }

View File

@ -39,7 +39,13 @@ import org.apache.hc.core5.http.protocol.HttpContext;
* implementation. * implementation.
* *
* @since 4.1 * @since 4.1
* @deprecated Do not use. the NTLM authentication scheme is no longer supported.
* Consider using Basic or Bearer authentication with TLS instead.
*
* @see BasicSchemeFactory
* @see BearerSchemeFactory
*/ */
@Deprecated
@Contract(threading = ThreadingBehavior.STATELESS) @Contract(threading = ThreadingBehavior.STATELESS)
public class NTLMSchemeFactory implements AuthSchemeFactory { public class NTLMSchemeFactory implements AuthSchemeFactory {

View File

@ -36,9 +36,8 @@ import java.net.URL;
import org.apache.hc.client5.http.auth.AuthScope; import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.Credentials; import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.auth.CredentialsStore; import org.apache.hc.client5.http.auth.CredentialsStore;
import org.apache.hc.client5.http.auth.NTCredentials;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.auth.StandardAuthScheme; import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
@ -54,6 +53,7 @@ import org.apache.hc.core5.util.Args;
* @since 4.3 * @since 4.3
*/ */
@Contract(threading = ThreadingBehavior.SAFE) @Contract(threading = ThreadingBehavior.SAFE)
@SuppressWarnings("deprecation")
public class SystemDefaultCredentialsProvider implements CredentialsStore { public class SystemDefaultCredentialsProvider implements CredentialsStore {
private final BasicCredentialsProvider internal; private final BasicCredentialsProvider internal;
@ -126,11 +126,12 @@ public class SystemDefaultCredentialsProvider implements CredentialsStore {
if (systemcreds != null) { if (systemcreds != null) {
final String domain = System.getProperty("http.auth.ntlm.domain"); final String domain = System.getProperty("http.auth.ntlm.domain");
if (domain != null) { if (domain != null) {
return new NTCredentials(systemcreds.getUserName(), systemcreds.getPassword(), null, domain); return new org.apache.hc.client5.http.auth.NTCredentials(
systemcreds.getUserName(), systemcreds.getPassword(), null, domain);
} }
if (StandardAuthScheme.NTLM.equalsIgnoreCase(authScope.getSchemeName())) { if (StandardAuthScheme.NTLM.equalsIgnoreCase(authScope.getSchemeName())) {
// Domain may be specified in a fully qualified user name // Domain may be specified in a fully qualified user name
return new NTCredentials( return new org.apache.hc.client5.http.auth.NTCredentials(
systemcreds.getUserName(), systemcreds.getPassword(), null, null); systemcreds.getUserName(), systemcreds.getPassword(), null, null);
} }
return new UsernamePasswordCredentials(systemcreds.getUserName(), systemcreds.getPassword()); return new UsernamePasswordCredentials(systemcreds.getUserName(), systemcreds.getPassword());

View File

@ -70,7 +70,6 @@ import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory; import org.apache.hc.client5.http.impl.auth.BearerSchemeFactory;
import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory; import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory; import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory;
import org.apache.hc.client5.http.impl.auth.NTLMSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory; import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SystemDefaultCredentialsProvider; import org.apache.hc.client5.http.impl.auth.SystemDefaultCredentialsProvider;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
@ -966,7 +965,6 @@ public class HttpClientBuilder {
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE) .register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE) .register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE) .register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT) .register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT) .register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
.build(); .build();

View File

@ -49,7 +49,6 @@ import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory; import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
import org.apache.hc.client5.http.impl.auth.HttpAuthenticator; import org.apache.hc.client5.http.impl.auth.HttpAuthenticator;
import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory; import org.apache.hc.client5.http.impl.auth.KerberosSchemeFactory;
import org.apache.hc.client5.http.impl.auth.NTLMSchemeFactory;
import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory; import org.apache.hc.client5.http.impl.auth.SPNegoSchemeFactory;
import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory; import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
@ -121,7 +120,6 @@ public class ProxyClient {
this.authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create() this.authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE) .register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE) .register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT) .register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT) .register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
.build(); .build();

View File

@ -35,6 +35,7 @@ import java.io.ObjectOutputStream;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation")
public class TestCredentials { public class TestCredentials {
@Test @Test

View File

@ -70,7 +70,7 @@ public class TestRequestConfig {
.setCircularRedirectsAllowed(true) .setCircularRedirectsAllowed(true)
.setMaxRedirects(100) .setMaxRedirects(100)
.setCookieSpec(StandardCookieSpec.STRICT) .setCookieSpec(StandardCookieSpec.STRICT)
.setTargetPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.NTLM)) .setTargetPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.BEARER))
.setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.DIGEST)) .setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.DIGEST))
.setContentCompressionEnabled(false) .setContentCompressionEnabled(false)
.build(); .build();
@ -82,7 +82,7 @@ public class TestRequestConfig {
Assertions.assertTrue(config.isCircularRedirectsAllowed()); Assertions.assertTrue(config.isCircularRedirectsAllowed());
Assertions.assertEquals(100, config.getMaxRedirects()); Assertions.assertEquals(100, config.getMaxRedirects());
Assertions.assertEquals(StandardCookieSpec.STRICT, config.getCookieSpec()); Assertions.assertEquals(StandardCookieSpec.STRICT, config.getCookieSpec());
Assertions.assertEquals(Collections.singletonList(StandardAuthScheme.NTLM), config.getTargetPreferredAuthSchemes()); Assertions.assertEquals(Collections.singletonList(StandardAuthScheme.BEARER), config.getTargetPreferredAuthSchemes());
Assertions.assertEquals(Collections.singletonList(StandardAuthScheme.DIGEST), config.getProxyPreferredAuthSchemes()); Assertions.assertEquals(Collections.singletonList(StandardAuthScheme.DIGEST), config.getProxyPreferredAuthSchemes());
Assertions.assertFalse(config.isContentCompressionEnabled()); Assertions.assertFalse(config.isContentCompressionEnabled());
} }

View File

@ -208,7 +208,7 @@ public class ClientConfiguration {
final RequestConfig defaultRequestConfig = RequestConfig.custom() final RequestConfig defaultRequestConfig = RequestConfig.custom()
.setCookieSpec(StandardCookieSpec.STRICT) .setCookieSpec(StandardCookieSpec.STRICT)
.setExpectContinueEnabled(true) .setExpectContinueEnabled(true)
.setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.NTLM, StandardAuthScheme.DIGEST)) .setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.DIGEST))
.setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.BASIC)) .setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.BASIC))
.build(); .build();

View File

@ -315,19 +315,6 @@ public class TestAuthChallengeParser {
assertThat(params1.get(1), NameValuePairMatcher.equals("blah", null)); assertThat(params1.get(1), NameValuePairMatcher.equals("blah", null));
} }
@Test
public void testParseEmptyNTLMAuthChallenge() throws Exception {
final CharArrayBuffer buffer = new CharArrayBuffer(64);
buffer.append(StandardAuthScheme.NTLM);
final ParserCursor cursor = new ParserCursor(0, buffer.length());
final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
Assertions.assertNotNull(challenges);
Assertions.assertEquals(1, challenges.size());
final AuthChallenge challenge1 = challenges.get(0);
Assertions.assertEquals(StandardAuthScheme.NTLM, challenge1.getSchemeName());
Assertions.assertNull(challenge1.getValue());
}
@Test @Test
public void testParseParameterAndToken68AuthChallengeMix() throws Exception { public void testParseParameterAndToken68AuthChallengeMix() throws Exception {
final CharArrayBuffer buffer = new CharArrayBuffer(64); final CharArrayBuffer buffer = new CharArrayBuffer(64);

View File

@ -66,12 +66,4 @@ public class TestBasicAuthCache {
Assertions.assertNull(cache.get(new HttpHost("localhost", 80))); Assertions.assertNull(cache.get(new HttpHost("localhost", 80)));
} }
@Test
public void testStoreNonSerializable() throws Exception {
final BasicAuthCache cache = new BasicAuthCache();
final AuthScheme authScheme = new NTLMScheme();
cache.put(new HttpHost("localhost", 80), authScheme);
Assertions.assertNull(cache.get(new HttpHost("localhost", 80)));
}
} }

View File

@ -94,7 +94,7 @@ public class TestHttpAuthenticator {
this.authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create() this.authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE) .register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE) .register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE).build(); .build();
this.context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry); this.context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry);
this.httpAuthenticator = new HttpAuthenticator(); this.httpAuthenticator = new HttpAuthenticator();
} }

View File

@ -35,6 +35,7 @@ import java.util.Random;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation")
public class TestNTLMEngineImpl { public class TestNTLMEngineImpl {
@Test @Test

View File

@ -37,6 +37,7 @@ import org.junit.jupiter.api.Test;
/** /**
* Unit tests for {@link NTLMScheme}. * Unit tests for {@link NTLMScheme}.
*/ */
@SuppressWarnings("deprecation")
public class TestNTLMScheme { public class TestNTLMScheme {
@Test @Test

View File

@ -45,7 +45,6 @@ import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.EntityBuilder; import org.apache.hc.client5.http.entity.EntityBuilder;
import org.apache.hc.client5.http.impl.auth.BasicScheme; import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder; import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
import org.apache.hc.client5.http.impl.auth.NTLMScheme;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.ClassicHttpResponse;
@ -209,7 +208,14 @@ public class TestProtocolExec {
final AuthExchange authExchange = new AuthExchange(); final AuthExchange authExchange = new AuthExchange();
authExchange.setState(AuthExchange.State.SUCCESS); authExchange.setState(AuthExchange.State.SUCCESS);
authExchange.select(new NTLMScheme()); authExchange.select(new BasicScheme() {
@Override
public boolean isConnectionBased() {
return true;
}
});
context.setAuthExchange(target, authExchange); context.setAuthExchange(target, authExchange);
context.setCredentialsProvider(CredentialsProviderBuilder.create() context.setCredentialsProvider(CredentialsProviderBuilder.create()

View File

@ -44,7 +44,6 @@ import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.EntityBuilder; import org.apache.hc.client5.http.entity.EntityBuilder;
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy; import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
import org.apache.hc.client5.http.impl.auth.BasicScheme; import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.impl.auth.NTLMScheme;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.protocol.RedirectLocations; import org.apache.hc.client5.http.protocol.RedirectLocations;
import org.apache.hc.client5.http.protocol.RedirectStrategy; import org.apache.hc.client5.http.protocol.RedirectStrategy;
@ -187,7 +186,14 @@ public class TestRedirectExec {
targetAuthExchange.select(new BasicScheme()); targetAuthExchange.select(new BasicScheme());
final AuthExchange proxyAuthExchange = new AuthExchange(); final AuthExchange proxyAuthExchange = new AuthExchange();
proxyAuthExchange.setState(AuthExchange.State.SUCCESS); proxyAuthExchange.setState(AuthExchange.State.SUCCESS);
proxyAuthExchange.select(new NTLMScheme()); proxyAuthExchange.select(new BasicScheme() {
@Override
public boolean isConnectionBased() {
return true;
}
});
context.setAuthExchange(target, targetAuthExchange); context.setAuthExchange(target, targetAuthExchange);
context.setAuthExchange(proxy, proxyAuthExchange); context.setAuthExchange(proxy, proxyAuthExchange);

View File

@ -123,11 +123,6 @@
<artifactId>httpclient5-fluent</artifactId> <artifactId>httpclient5-fluent</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5-win</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
@ -205,7 +200,6 @@
<module>httpclient5</module> <module>httpclient5</module>
<module>httpclient5-fluent</module> <module>httpclient5-fluent</module>
<module>httpclient5-cache</module> <module>httpclient5-cache</module>
<module>httpclient5-win</module>
<module>httpclient5-testing</module> <module>httpclient5-testing</module>
</modules> </modules>