NTLM scheme deprecated and disabled by default
This commit is contained in:
parent
8aa4fbc8de
commit
83c6079e65
|
@ -30,7 +30,6 @@ The JAR packages can be found in the target folders of their respective modules
|
|||
httpclient5/target/httpclient5-<VERSION>.jar
|
||||
httpclient5-cache/target/httpclient5-cache-<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
|
||||
|
||||
where <VERSION> is the release version
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.apache.hc.core5.http.message.StatusLine;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TestByteArrayCacheEntrySerializer {
|
||||
|
||||
private ByteArrayCacheEntrySerializer impl;
|
||||
|
|
|
@ -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.Credentials;
|
||||
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.config.ConnectionConfig;
|
||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||
|
@ -186,10 +185,14 @@ public class Executor {
|
|||
return auth(host, new UsernamePasswordCredentials(username, password));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #auth(HttpHost, String, char[])}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Executor auth(final HttpHost host,
|
||||
final String username, final char[] password,
|
||||
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() {
|
||||
|
|
|
@ -77,11 +77,6 @@
|
|||
<artifactId>httpclient5-fluent</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5-win</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -125,6 +125,7 @@ public class TestSPNegoScheme {
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static class UseJaasCredentials implements Credentials {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
|
@ -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>
|
|
@ -43,7 +43,14 @@ import org.apache.hc.core5.util.LangUtils;
|
|||
* Windows specific attributes such as name of the domain the user belongs to.
|
||||
*
|
||||
* @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)
|
||||
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.
|
||||
* Essentially, the computer name for this machine.
|
||||
* @param domain The domain to authenticate within.
|
||||
* @deprecated (5.3) Use {@link #NTCredentials(char[], String, String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public NTCredentials(
|
||||
final String userName,
|
||||
final char[] password,
|
||||
|
@ -89,9 +94,7 @@ public class NTCredentials implements Credentials, Serializable {
|
|||
* Essentially, the computer name for this machine.
|
||||
* @param domain The domain to authenticate within.
|
||||
* @param netbiosDomain The netbios version of the domain name.
|
||||
@deprecated (5.3) Use {@link #NTCredentials(char[], String, String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public NTCredentials(
|
||||
final String userName,
|
||||
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
|
||||
* using the {@link #getWorkstationName()} method. The workstation name will be converted to uppercase
|
||||
* using the {@link java.util.Locale#ROOT} locale.
|
||||
* @since 5.3
|
||||
*/
|
||||
public NTCredentials(
|
||||
final char[] password,
|
||||
|
|
|
@ -57,7 +57,11 @@ public final class StandardAuthScheme {
|
|||
/**
|
||||
* The NTLM authentication scheme is a proprietary Microsoft Windows
|
||||
* 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";
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,6 @@ public class DefaultAuthenticationStrategy implements AuthenticationStrategy {
|
|||
Collections.unmodifiableList(Arrays.asList(
|
||||
StandardAuthScheme.SPNEGO,
|
||||
StandardAuthScheme.KERBEROS,
|
||||
StandardAuthScheme.NTLM,
|
||||
StandardAuthScheme.BEARER,
|
||||
StandardAuthScheme.DIGEST,
|
||||
StandardAuthScheme.BASIC));
|
||||
|
|
|
@ -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.DigestSchemeFactory;
|
||||
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.SystemDefaultCredentialsProvider;
|
||||
import org.apache.hc.client5.http.impl.nio.MultihomeConnectionInitiator;
|
||||
|
@ -822,7 +821,6 @@ public class H2AsyncClientBuilder {
|
|||
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
|
||||
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
|
||||
.build();
|
||||
|
|
|
@ -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.DigestSchemeFactory;
|
||||
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.SystemDefaultCredentialsProvider;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
|
@ -1009,7 +1008,6 @@ public class HttpAsyncClientBuilder {
|
|||
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
|
||||
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
|
||||
.build();
|
||||
|
|
|
@ -32,7 +32,10 @@ package org.apache.hc.client5.http.impl.auth;
|
|||
* Type2 challenge.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated Do not use. the NTLM authentication scheme is no longer supported
|
||||
*/
|
||||
@Deprecated
|
||||
public interface NTLMEngine {
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,10 @@ import org.apache.hc.client5.http.auth.AuthenticationException;
|
|||
* Signals NTLM protocol failure.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
public class NTLMEngineException extends AuthenticationException {
|
||||
|
||||
private static final long serialVersionUID = 6027981323731768824L;
|
||||
|
|
|
@ -48,7 +48,10 @@ import org.apache.hc.client5.http.utils.ByteArrayBuilder;
|
|||
* authentication protocol.
|
||||
*
|
||||
* @since 4.1
|
||||
*
|
||||
* @deprecated Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
final class NTLMEngineImpl implements NTLMEngine {
|
||||
|
||||
/** Unicode encoding */
|
||||
|
|
|
@ -30,13 +30,12 @@ import java.security.Principal;
|
|||
|
||||
import org.apache.hc.client5.http.auth.AuthChallenge;
|
||||
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.AuthenticationException;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||
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.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
|
@ -50,7 +49,14 @@ import org.slf4j.LoggerFactory;
|
|||
* and optimized for Windows platforms.
|
||||
*
|
||||
* @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 {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(NTLMScheme.class);
|
||||
|
@ -68,7 +74,7 @@ public final class NTLMScheme implements AuthScheme {
|
|||
|
||||
private State state;
|
||||
private String challenge;
|
||||
private NTCredentials credentials;
|
||||
private org.apache.hc.client5.http.auth.NTCredentials credentials;
|
||||
|
||||
public NTLMScheme(final NTLMEngine engine) {
|
||||
super();
|
||||
|
@ -134,8 +140,8 @@ public final class NTLMScheme implements AuthScheme {
|
|||
final AuthScope authScope = new AuthScope(host, null, getName());
|
||||
final Credentials credentials = credentialsProvider.getCredentials(
|
||||
authScope, context);
|
||||
if (credentials instanceof NTCredentials) {
|
||||
this.credentials = (NTCredentials) credentials;
|
||||
if (credentials instanceof org.apache.hc.client5.http.auth.NTCredentials) {
|
||||
this.credentials = (org.apache.hc.client5.http.auth.NTCredentials) credentials;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,13 @@ import org.apache.hc.core5.http.protocol.HttpContext;
|
|||
* implementation.
|
||||
*
|
||||
* @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)
|
||||
public class NTLMSchemeFactory implements AuthSchemeFactory {
|
||||
|
||||
|
|
|
@ -36,9 +36,8 @@ import java.net.URL;
|
|||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
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.UsernamePasswordCredentials;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
|
@ -54,6 +53,7 @@ import org.apache.hc.core5.util.Args;
|
|||
* @since 4.3
|
||||
*/
|
||||
@Contract(threading = ThreadingBehavior.SAFE)
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SystemDefaultCredentialsProvider implements CredentialsStore {
|
||||
|
||||
private final BasicCredentialsProvider internal;
|
||||
|
@ -126,11 +126,12 @@ public class SystemDefaultCredentialsProvider implements CredentialsStore {
|
|||
if (systemcreds != null) {
|
||||
final String domain = System.getProperty("http.auth.ntlm.domain");
|
||||
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())) {
|
||||
// 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);
|
||||
}
|
||||
return new UsernamePasswordCredentials(systemcreds.getUserName(), systemcreds.getPassword());
|
||||
|
|
|
@ -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.DigestSchemeFactory;
|
||||
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.SystemDefaultCredentialsProvider;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||
|
@ -966,7 +965,6 @@ public class HttpClientBuilder {
|
|||
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.BEARER, BearerSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
|
||||
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
|
||||
.build();
|
||||
|
|
|
@ -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.HttpAuthenticator;
|
||||
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.io.ManagedHttpClientConnectionFactory;
|
||||
import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
|
||||
|
@ -121,7 +120,6 @@ public class ProxyClient {
|
|||
this.authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.SPNEGO, SPNegoSchemeFactory.DEFAULT)
|
||||
.register(StandardAuthScheme.KERBEROS, KerberosSchemeFactory.DEFAULT)
|
||||
.build();
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.io.ObjectOutputStream;
|
|||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TestCredentials {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -70,7 +70,7 @@ public class TestRequestConfig {
|
|||
.setCircularRedirectsAllowed(true)
|
||||
.setMaxRedirects(100)
|
||||
.setCookieSpec(StandardCookieSpec.STRICT)
|
||||
.setTargetPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.NTLM))
|
||||
.setTargetPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.BEARER))
|
||||
.setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.DIGEST))
|
||||
.setContentCompressionEnabled(false)
|
||||
.build();
|
||||
|
@ -82,7 +82,7 @@ public class TestRequestConfig {
|
|||
Assertions.assertTrue(config.isCircularRedirectsAllowed());
|
||||
Assertions.assertEquals(100, config.getMaxRedirects());
|
||||
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.assertFalse(config.isContentCompressionEnabled());
|
||||
}
|
||||
|
|
|
@ -208,7 +208,7 @@ public class ClientConfiguration {
|
|||
final RequestConfig defaultRequestConfig = RequestConfig.custom()
|
||||
.setCookieSpec(StandardCookieSpec.STRICT)
|
||||
.setExpectContinueEnabled(true)
|
||||
.setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.NTLM, StandardAuthScheme.DIGEST))
|
||||
.setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.DIGEST))
|
||||
.setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.BASIC))
|
||||
.build();
|
||||
|
||||
|
|
|
@ -315,19 +315,6 @@ public class TestAuthChallengeParser {
|
|||
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
|
||||
public void testParseParameterAndToken68AuthChallengeMix() throws Exception {
|
||||
final CharArrayBuffer buffer = new CharArrayBuffer(64);
|
||||
|
|
|
@ -66,12 +66,4 @@ public class TestBasicAuthCache {
|
|||
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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public class TestHttpAuthenticator {
|
|||
this.authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||
.register(StandardAuthScheme.BASIC, BasicSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.DIGEST, DigestSchemeFactory.INSTANCE)
|
||||
.register(StandardAuthScheme.NTLM, NTLMSchemeFactory.INSTANCE).build();
|
||||
.build();
|
||||
this.context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry);
|
||||
this.httpAuthenticator = new HttpAuthenticator();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Random;
|
|||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TestNTLMEngineImpl {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.junit.jupiter.api.Test;
|
|||
/**
|
||||
* Unit tests for {@link NTLMScheme}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TestNTLMScheme {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -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.impl.auth.BasicScheme;
|
||||
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.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
|
@ -209,7 +208,14 @@ public class TestProtocolExec {
|
|||
|
||||
final AuthExchange authExchange = new AuthExchange();
|
||||
authExchange.setState(AuthExchange.State.SUCCESS);
|
||||
authExchange.select(new NTLMScheme());
|
||||
authExchange.select(new BasicScheme() {
|
||||
|
||||
@Override
|
||||
public boolean isConnectionBased() {
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
context.setAuthExchange(target, authExchange);
|
||||
|
||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||
|
|
|
@ -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.impl.DefaultRedirectStrategy;
|
||||
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.RedirectLocations;
|
||||
import org.apache.hc.client5.http.protocol.RedirectStrategy;
|
||||
|
@ -187,7 +186,14 @@ public class TestRedirectExec {
|
|||
targetAuthExchange.select(new BasicScheme());
|
||||
final AuthExchange proxyAuthExchange = new AuthExchange();
|
||||
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(proxy, proxyAuthExchange);
|
||||
|
||||
|
|
6
pom.xml
6
pom.xml
|
@ -123,11 +123,6 @@
|
|||
<artifactId>httpclient5-fluent</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5-win</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
@ -205,7 +200,6 @@
|
|||
<module>httpclient5</module>
|
||||
<module>httpclient5-fluent</module>
|
||||
<module>httpclient5-cache</module>
|
||||
<module>httpclient5-win</module>
|
||||
<module>httpclient5-testing</module>
|
||||
</modules>
|
||||
|
||||
|
|
Loading…
Reference in New Issue