View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.testing.sync;
28  
29  import java.io.IOException;
30  
31  import org.apache.hc.client5.http.auth.StandardAuthScheme;
32  import org.apache.hc.client5.http.auth.AuthScope;
33  import org.apache.hc.client5.http.auth.NTCredentials;
34  import org.apache.hc.client5.http.classic.methods.HttpGet;
35  import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
36  import org.apache.hc.client5.http.impl.classic.HttpClients;
37  import org.apache.hc.client5.http.protocol.HttpClientContext;
38  import org.apache.hc.core5.http.ClassicHttpRequest;
39  import org.apache.hc.core5.http.ClassicHttpResponse;
40  import org.apache.hc.core5.http.HttpException;
41  import org.apache.hc.core5.http.HttpHeaders;
42  import org.apache.hc.core5.http.HttpHost;
43  import org.apache.hc.core5.http.HttpStatus;
44  import org.apache.hc.core5.http.io.HttpRequestHandler;
45  import org.apache.hc.core5.http.io.entity.EntityUtils;
46  import org.apache.hc.core5.http.protocol.HttpContext;
47  import org.junit.Assert;
48  import org.junit.Test;
49  
50  /**
51   * Unit tests for some of the NTLM auth functionality..
52   */
53  public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
54  
55      static class NtlmResponseHandler implements HttpRequestHandler {
56  
57          @Override
58          public void handle(
59                  final ClassicHttpRequest request,
60                  final ClassicHttpResponse response,
61                  final HttpContext context) throws HttpException, IOException {
62              response.setCode(HttpStatus.SC_UNAUTHORIZED);
63              response.setHeader("Connection", "Keep-Alive");
64              response.setHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.NTLM);
65          }
66      }
67  
68      @Test
69      public void testNTLMAuthenticationFailure() throws Exception {
70          this.server.registerHandler("*", new NtlmResponseHandler());
71  
72          final HttpHost target = start();
73  
74          final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
75          credsProvider.setCredentials(new AuthScope(null, null, -1, null ,null),
76                  new NTCredentials("test", "test".toCharArray(), null, null));
77  
78          this.httpclient = HttpClients.custom()
79                  .setDefaultCredentialsProvider(credsProvider)
80                  .build();
81  
82          final HttpContext context = HttpClientContext.create();
83          final HttpGet httpget = new HttpGet("/");
84  
85          final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
86          EntityUtils.consume(response.getEntity());
87          Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED,
88                  response.getCode());
89      }
90  
91      static class NtlmType2MessageResponseHandler implements HttpRequestHandler {
92  
93          private final String authenticateHeaderValue;
94  
95          public NtlmType2MessageResponseHandler(final String type2Message) {
96              this.authenticateHeaderValue = StandardAuthScheme.NTLM + " " + type2Message;
97          }
98  
99          @Override
100         public void handle(
101                 final ClassicHttpRequest request,
102                 final ClassicHttpResponse response,
103                 final HttpContext context) throws HttpException, IOException {
104             response.setCode(HttpStatus.SC_UNAUTHORIZED);
105             response.setHeader("Connection", "Keep-Alive");
106             if (!request.containsHeader(HttpHeaders.AUTHORIZATION)) {
107                 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.NTLM);
108             } else {
109                 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue);
110             }
111         }
112     }
113 
114     @Test
115     public void testNTLMv1Type2Message() throws Exception {
116         this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
117                 "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
118                 "AGUAcgB2AGUAcgA="));
119         final HttpHost target = start();
120 
121         final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
122         credsProvider.setCredentials(new AuthScope(null, null, -1, null ,null),
123                 new NTCredentials("test", "test".toCharArray(), null, null));
124 
125         this.httpclient = HttpClients.custom()
126                 .setDefaultCredentialsProvider(credsProvider)
127                 .build();
128 
129         final HttpContext context = HttpClientContext.create();
130         final HttpGet httpget = new HttpGet("/");
131 
132         final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
133         EntityUtils.consume(response.getEntity());
134         Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED,
135                 response.getCode());
136     }
137 
138     @Test
139     public void testNTLMv2Type2Message() throws Exception {
140         this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
141                 "AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" +
142                 "AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA="));
143         final HttpHost target = start();
144 
145         final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
146         credsProvider.setCredentials(new AuthScope(null, null, -1, null ,null),
147                 new NTCredentials("test", "test".toCharArray(), null, null));
148 
149         this.httpclient = HttpClients.custom()
150                 .setDefaultCredentialsProvider(credsProvider)
151                 .build();
152 
153         final HttpContext context = HttpClientContext.create();
154         final HttpGet httpget = new HttpGet("/");
155 
156         final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
157         EntityUtils.consume(response.getEntity());
158         Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED,
159                 response.getCode());
160     }
161 
162     static class NtlmType2MessageOnlyResponseHandler implements HttpRequestHandler {
163 
164         private final String authenticateHeaderValue;
165 
166         public NtlmType2MessageOnlyResponseHandler(final String type2Message) {
167             this.authenticateHeaderValue = StandardAuthScheme.NTLM + " " + type2Message;
168         }
169 
170         @Override
171         public void handle(
172                 final ClassicHttpRequest request,
173                 final ClassicHttpResponse response,
174                 final HttpContext context) throws HttpException, IOException {
175             response.setCode(HttpStatus.SC_UNAUTHORIZED);
176             response.setHeader("Connection", "Keep-Alive");
177             response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue);
178         }
179     }
180 
181     @Test
182     public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception {
183         this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
184                 "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
185                 "AGUAcgB2AGUAcgA="));
186 
187         final HttpHost target = start();
188 
189         final HttpClientContext context = HttpClientContext.create();
190         final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
191         credsProvider.setCredentials(new AuthScope(null, null, -1, null ,null),
192                 new NTCredentials("test", "test".toCharArray(), null, null));
193         context.setCredentialsProvider(credsProvider);
194         final HttpGet httpget = new HttpGet("/");
195 
196         final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
197         EntityUtils.consume(response.getEntity());
198         Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED,
199                 response.getCode());
200     }
201 
202     @Test
203     public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception {
204         this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
205                 "AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
206                 "ZXJ2ZXI="));
207 
208         final HttpHost target = start();
209 
210         final HttpClientContext context = HttpClientContext.create();
211         final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
212         credsProvider.setCredentials(new AuthScope(null, null, -1, null ,null),
213                 new NTCredentials("test", "test".toCharArray(), null, null));
214         context.setCredentialsProvider(credsProvider);
215         final HttpGet httpget = new HttpGet("/");
216 
217         final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
218         EntityUtils.consume(response.getEntity());
219         Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED,
220                 response.getCode());
221     }
222 
223 }