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
28
29
30 package org.apache.commons.httpclient.auth;
31
32 import java.io.IOException;
33
34 import junit.framework.Test;
35 import junit.framework.TestSuite;
36
37 import org.apache.commons.httpclient.FakeHttpMethod;
38 import org.apache.commons.httpclient.Header;
39 import org.apache.commons.httpclient.HttpClientTestBase;
40 import org.apache.commons.httpclient.HttpState;
41 import org.apache.commons.httpclient.HttpStatus;
42 import org.apache.commons.httpclient.HttpVersion;
43 import org.apache.commons.httpclient.NTCredentials;
44 import org.apache.commons.httpclient.methods.GetMethod;
45 import org.apache.commons.httpclient.protocol.Protocol;
46 import org.apache.commons.httpclient.server.HttpService;
47 import org.apache.commons.httpclient.server.RequestLine;
48 import org.apache.commons.httpclient.server.SimpleRequest;
49 import org.apache.commons.httpclient.server.SimpleResponse;
50
51 /***
52 * Test Methods for NTLM Authentication.
53 *
54 * @author Rodney Waldhoff
55 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
56 * @version $Id: TestNTLMAuth.java 608014 2008-01-02 05:48:53Z rolandw $
57 */
58 public class TestNTLMAuth extends HttpClientTestBase {
59
60
61 public TestNTLMAuth(String testName) throws IOException {
62 super(testName);
63 }
64
65
66 public static void main(String args[]) {
67 String[] testCaseName = { TestNTLMAuth.class.getName() };
68 junit.textui.TestRunner.main(testCaseName);
69 }
70
71
72
73 public static Test suite() {
74 return new TestSuite(TestNTLMAuth.class);
75 }
76
77
78
79 public void testNTLMAuthenticationResponse1() throws Exception {
80 String challenge = "NTLM";
81 String expected = "NTLM TlRMTVNTUAABAAAABlIAAAYABgAkAAAABAAEACAAAABIT" +
82 "1NURE9NQUlO";
83 NTCredentials cred = new NTCredentials("username","password", "host", "domain");
84 FakeHttpMethod method = new FakeHttpMethod();
85 AuthScheme authscheme = new NTLMScheme(challenge);
86 authscheme.processChallenge(challenge);
87 String response = authscheme.authenticate(cred, method);
88 assertEquals(expected, response);
89 assertFalse(authscheme.isComplete());
90 }
91
92 public void testNTLMAuthenticationResponse2() throws Exception {
93 String challenge =
94 "NTLM TlRMTVNTUAACAAAACgAKADAAAAAGgoEAPc4kP4LtCV8AAAAAAAAAAJ4AngA" +
95 "6AAAASU5UUkFFUEhPWAIAFABJAE4AVABSAEEARQBQAEgATwBYAAEAEgBCAE8AQQB" +
96 "SAEQAUgBPAE8ATQAEACgAaQBuAHQAcgBhAGUAcABoAG8AeAAuAGUAcABoAG8AeAA" +
97 "uAGMAbwBtAAMAPABCAG8AYQByAGQAcgBvAG8AbQAuAGkAbgB0AHIAYQBlAHAAaAB" +
98 "vAHgALgBlAHAAaABvAHgALgBjAG8AbQAAAAAA";
99
100 String expected = "NTLM TlRMTVNTUAADAAAAGAAYAFIAAAAAAAAAagAAAAYABgB" +
101 "AAAAACAAIAEYAAAAEAAQATgAAAAAAAABqAAAABlIAAERPTUFJTlVTRVJOQU1FSE" +
102 "9TVAaC+vLxUEHnUtpItj9Dp4kzwQfd61Lztg==";
103 NTCredentials cred = new NTCredentials("username","password", "host", "domain");
104 FakeHttpMethod method = new FakeHttpMethod();
105 AuthScheme authscheme = new NTLMScheme(challenge);
106 authscheme.processChallenge(challenge);
107 String response = authscheme.authenticate(cred, method);
108 assertEquals(expected, response);
109 assertTrue(authscheme.isComplete());
110 }
111
112 private class NTLMAuthService implements HttpService {
113
114 public NTLMAuthService() {
115 super();
116 }
117
118 public boolean process(final SimpleRequest request, final SimpleResponse response)
119 throws IOException
120 {
121 RequestLine requestLine = request.getRequestLine();
122 HttpVersion ver = requestLine.getHttpVersion();
123 Header auth = request.getFirstHeader("Authorization");
124 if (auth == null) {
125 response.setStatusLine(ver, HttpStatus.SC_UNAUTHORIZED);
126 response.addHeader(new Header("WWW-Authenticate", "NTLM"));
127 response.setBodyString("Authorization required");
128 return true;
129 } else {
130 String authstr = auth.getValue();
131
132 if (authstr.equals("NTLM TlRMTVNTUAABAAAABlIAAAYABgAkAAAABAAEACAAAABIT1NURE9NQUlO")) {
133 response.setStatusLine(ver, HttpStatus.SC_UNAUTHORIZED);
134 response.addHeader(new Header("WWW-Authenticate",
135 "NTLM TlRMTVNTUAACAAAAAAAAACgAAAABggAAU3J2Tm9uY2UAAAAAAAAAAA=="));
136 response.setBodyString("Authorization required");
137 return true;
138 } if (authstr.equals("NTLM TlRMTVNTUAADAAAAGAAYAFIAAAAAAAAAagAAAAYABgBAAAAACAAIAEYAAAAEAAQATgAAAAAAAABqAAAABlIAAERPTUFJTlVTRVJOQU1FSE9TVJxndWIt46bHm11TPrt5Z6wrz7ziq04yRA==")) {
139 response.setStatusLine(ver, HttpStatus.SC_OK);
140 response.setBodyString("Authorization successful");
141 return true;
142 } else {
143 response.setStatusLine(ver, HttpStatus.SC_UNAUTHORIZED);
144 response.addHeader(new Header("WWW-Authenticate", "NTLM"));
145 response.setBodyString("Authorization required");
146 return true;
147 }
148 }
149 }
150 }
151
152
153 public void testNTLMAuthenticationRetry() throws Exception {
154
155 this.server.setHttpService(new NTLMAuthService());
156
157
158 this.client.getHostConfiguration().setHost(
159 server.getLocalAddress(), server.getLocalPort(),
160 Protocol.getProtocol("http"));
161
162 this.client.getState().setCredentials(AuthScope.ANY,
163 new NTCredentials("username", "password", "host", "domain"));
164
165 FakeHttpMethod httpget = new FakeHttpMethod("/");
166 try {
167 client.executeMethod(httpget);
168 } finally {
169 httpget.releaseConnection();
170 }
171 assertNull(httpget.getResponseHeader("WWW-Authenticate"));
172 assertEquals(200, httpget.getStatusCode());
173 }
174
175 private class PreemptiveNTLMAuthService implements HttpService {
176
177 public PreemptiveNTLMAuthService() {
178 super();
179 }
180
181 public boolean process(final SimpleRequest request, final SimpleResponse response)
182 throws IOException
183 {
184 RequestLine requestLine = request.getRequestLine();
185 HttpVersion ver = requestLine.getHttpVersion();
186 Header auth = request.getFirstHeader("Authorization");
187 if (auth == null) {
188 response.setStatusLine(ver, HttpStatus.SC_BAD_REQUEST);
189 response.setBodyString("Authorization header missing");
190 return true;
191 } else {
192 String authstr = auth.getValue();
193
194 if (authstr.indexOf("NTLM") != -1) {
195 response.setStatusLine(ver, HttpStatus.SC_OK);
196 return true;
197 } else if (authstr.indexOf("Basic") != -1) {
198 response.setStatusLine(ver, HttpStatus.SC_UNAUTHORIZED);
199 response.addHeader(new Header("WWW-Authenticate", "Negotiate"));
200 response.addHeader(new Header("WWW-Authenticate", "NTLM"));
201 response.setBodyString("Authorization required");
202 return true;
203 } else {
204 response.setStatusLine(ver, HttpStatus.SC_BAD_REQUEST);
205 response.setBodyString("Unknown auth type: " + authstr);
206 return true;
207 }
208 }
209 }
210 }
211
212 /***
213 * Make sure preemptive authorization works when the server requires NLM.
214 * @throws Exception
215 */
216 public void testPreemptiveAuthorization() throws Exception {
217
218 NTCredentials creds =
219 new NTCredentials("testuser", "testpass", "host", "domain");
220
221 HttpState state = new HttpState();
222 state.setCredentials(AuthScope.ANY, creds);
223 this.client.setState(state);
224 this.client.getParams().setAuthenticationPreemptive(true);
225
226 this.server.setHttpService(new PreemptiveNTLMAuthService());
227
228 GetMethod httpget = new GetMethod("/test/");
229 try {
230 this.client.executeMethod(httpget);
231 } finally {
232 httpget.releaseConnection();
233 }
234 assertNotNull(httpget.getStatusLine());
235 assertEquals(HttpStatus.SC_OK, httpget.getStatusLine().getStatusCode());
236 }
237
238
239 }