1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.impl.auth.win;
28
29 import java.io.IOException;
30
31 import com.sun.jna.platform.win32.Sspi.CtxtHandle;
32 import com.sun.jna.platform.win32.Sspi.SecBufferDesc;
33 import com.sun.jna.platform.win32.Win32Exception;
34 import com.sun.jna.platform.win32.WinError;
35 import org.apache.http.HttpException;
36 import org.apache.http.HttpHost;
37 import org.apache.http.HttpRequest;
38 import org.apache.http.HttpResponse;
39 import org.apache.http.HttpStatus;
40 import org.apache.http.auth.AUTH;
41 import org.apache.http.auth.AuthScheme;
42 import org.apache.http.auth.AuthSchemeProvider;
43 import org.apache.http.client.CredentialsProvider;
44 import org.apache.http.client.config.AuthSchemes;
45 import org.apache.http.client.methods.CloseableHttpResponse;
46 import org.apache.http.client.methods.HttpGet;
47 import org.apache.http.config.Registry;
48 import org.apache.http.config.RegistryBuilder;
49 import org.apache.http.impl.client.CloseableHttpClient;
50 import org.apache.http.impl.client.HttpClientBuilder;
51 import org.apache.http.impl.client.SystemDefaultCredentialsProvider;
52 import org.apache.http.impl.client.WinHttpClients;
53 import org.apache.http.localserver.LocalServerTestBase;
54 import org.apache.http.protocol.HttpContext;
55 import org.apache.http.protocol.HttpRequestHandler;
56 import org.apache.http.util.EntityUtils;
57 import org.junit.After;
58 import org.junit.Assume;
59 import org.junit.Before;
60 import org.junit.Test;
61
62
63
64
65 public class TestWindowsNegotiateScheme extends LocalServerTestBase {
66
67 @Before @Override
68 public void setUp() throws Exception {
69 super.setUp();
70 this.serverBootstrap.registerHandler("/", new HttpRequestHandler() {
71
72 @Override
73 public void handle(
74 final HttpRequest request,
75 final HttpResponse response,
76 final HttpContext context) throws HttpException, IOException {
77 response.addHeader(AUTH.WWW_AUTH, AuthSchemes.SPNEGO);
78 response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
79 }
80
81 });
82 }
83
84 @After @Override
85 public void shutDown() throws Exception {
86 super.shutDown();
87 }
88
89 @Test(timeout=30000)
90 public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
91 Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
92
93
94
95
96
97
98
99
100
101 final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
102 .register(AuthSchemes.SPNEGO, new AuthSchemeProvider() {
103 @Override
104 public AuthScheme create(final HttpContext context) {
105 return new WindowsNegotiateSchemeGetTokenFail(AuthSchemes.SPNEGO, "HTTP/example.com");
106 }
107 }).build();
108 final CredentialsProvider credsProvider =
109 new WindowsCredentialsProvider(new SystemDefaultCredentialsProvider());
110 final CloseableHttpClient customClient = HttpClientBuilder.create()
111 .setDefaultCredentialsProvider(credsProvider)
112 .setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
113 try {
114 final HttpHost target = start();
115 final HttpGet httpGet = new HttpGet("/");
116 final CloseableHttpResponse response = customClient.execute(target, httpGet);
117 try {
118 EntityUtils.consume(response.getEntity());
119 } finally {
120 response.close();
121 }
122 }finally {
123 customClient.close();
124 }
125 }
126
127 private final class WindowsNegotiateSchemeGetTokenFail extends WindowsNegotiateScheme {
128
129 public WindowsNegotiateSchemeGetTokenFail(final String scheme, final String servicePrincipalName) {
130 super(scheme, servicePrincipalName);
131 }
132
133 @Override
134 String getToken(final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) {
135 dispose();
136
137
138
139 throw new Win32Exception(WinError.SEC_E_TARGET_UNKNOWN);
140 }
141
142 }
143
144 }