KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > auth > TestDigestAuth


1 /*
2  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/auth/TestDigestAuth.java,v 1.2 2004/11/07 12:31:42 olegk Exp $
3  * $Revision: 480424 $
4  * $Date: 2006-11-29 05:56:49 +0000 (Wed, 29 Nov 2006) $
5  * ====================================================================
6  *
7  * Licensed to the Apache Software Foundation (ASF) under one or more
8  * contributor license agreements. See the NOTICE file distributed with
9  * this work for additional information regarding copyright ownership.
10  * The ASF licenses this file to You under the Apache License, Version 2.0
11  * (the "License"); you may not use this file except in compliance with
12  * the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ====================================================================
22  *
23  * This software consists of voluntary contributions made by many
24  * individuals on behalf of the Apache Software Foundation. For more
25  * information on the Apache Software Foundation, please see
26  * <http://www.apache.org/>.
27  *
28  */

29
30 package org.apache.commons.httpclient.auth;
31
32 import java.io.IOException JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import org.apache.commons.httpclient.FakeHttpMethod;
36 import org.apache.commons.httpclient.Header;
37 import org.apache.commons.httpclient.HttpClient;
38 import org.apache.commons.httpclient.HttpStatus;
39 import org.apache.commons.httpclient.HttpVersion;
40 import org.apache.commons.httpclient.UsernamePasswordCredentials;
41 import org.apache.commons.httpclient.protocol.Protocol;
42 import org.apache.commons.httpclient.server.HttpService;
43 import org.apache.commons.httpclient.server.RequestLine;
44 import org.apache.commons.httpclient.server.SimpleHttpServer;
45 import org.apache.commons.httpclient.server.SimpleRequest;
46 import org.apache.commons.httpclient.server.SimpleResponse;
47
48 import junit.framework.Test;
49 import junit.framework.TestCase;
50 import junit.framework.TestSuite;
51
52 /**
53  * Test Methods for DigestScheme Authentication.
54  *
55  * @author Rodney Waldhoff
56  * @author <a HREF="mailto:jsdever@apache.org">Jeff Dever</a>
57  * @author <a HREF="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
58  */

59 public class TestDigestAuth extends TestCase {
60
61     // ------------------------------------------------------------ Constructor
62
public TestDigestAuth(String JavaDoc testName) {
63         super(testName);
64     }
65
66     // ------------------------------------------------------------------- Main
67
public static void main(String JavaDoc args[]) {
68         String JavaDoc[] testCaseName = { TestDigestAuth.class.getName() };
69         junit.textui.TestRunner.main(testCaseName);
70     }
71
72     // ------------------------------------------------------- TestCase Methods
73

74     public static Test suite() {
75         return new TestSuite(TestDigestAuth.class);
76     }
77
78     public void testDigestAuthenticationWithNoRealm() throws Exception JavaDoc {
79         String JavaDoc challenge = "Digest";
80         try {
81             AuthScheme authscheme = new DigestScheme();
82             authscheme.processChallenge(challenge);
83             fail("Should have thrown MalformedChallengeException");
84         } catch(MalformedChallengeException e) {
85             // expected
86
}
87     }
88
89     public void testDigestAuthenticationWithNoRealm2() throws Exception JavaDoc {
90         String JavaDoc challenge = "Digest ";
91         try {
92             AuthScheme authscheme = new DigestScheme();
93             authscheme.processChallenge(challenge);
94             fail("Should have thrown MalformedChallengeException");
95         } catch(MalformedChallengeException e) {
96             // expected
97
}
98     }
99
100     public void testDigestAuthenticationWithDefaultCreds() throws Exception JavaDoc {
101         String JavaDoc challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
102         FakeHttpMethod method = new FakeHttpMethod("/");
103         UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
104         AuthScheme authscheme = new DigestScheme();
105         authscheme.processChallenge(challenge);
106         String JavaDoc response = authscheme.authenticate(cred, method);
107         Map JavaDoc table = AuthChallengeParser.extractParams(response);
108         assertEquals("username", table.get("username"));
109         assertEquals("realm1", table.get("realm"));
110         assertEquals("/", table.get("uri"));
111         assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce"));
112         assertEquals("e95a7ddf37c2eab009568b1ed134f89a", table.get("response"));
113     }
114
115     public void testDigestAuthentication() throws Exception JavaDoc {
116         String JavaDoc challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
117         UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
118         FakeHttpMethod method = new FakeHttpMethod("/");
119         AuthScheme authscheme = new DigestScheme();
120         authscheme.processChallenge(challenge);
121         String JavaDoc response = authscheme.authenticate(cred, method);
122         Map JavaDoc table = AuthChallengeParser.extractParams(response);
123         assertEquals("username", table.get("username"));
124         assertEquals("realm1", table.get("realm"));
125         assertEquals("/", table.get("uri"));
126         assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce"));
127         assertEquals("e95a7ddf37c2eab009568b1ed134f89a", table.get("response"));
128     }
129
130     public void testDigestAuthenticationWithQueryStringInDigestURI() throws Exception JavaDoc {
131         String JavaDoc challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
132         UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
133         FakeHttpMethod method = new FakeHttpMethod("/");
134         method.setQueryString("param=value");
135         AuthScheme authscheme = new DigestScheme();
136         authscheme.processChallenge(challenge);
137         String JavaDoc response = authscheme.authenticate(cred, method);
138         Map JavaDoc table = AuthChallengeParser.extractParams(response);
139         assertEquals("username", table.get("username"));
140         assertEquals("realm1", table.get("realm"));
141         assertEquals("/?param=value", table.get("uri"));
142         assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce"));
143         assertEquals("a847f58f5fef0bc087bcb9c3eb30e042", table.get("response"));
144     }
145
146     public void testDigestAuthenticationWithMultipleRealms() throws Exception JavaDoc {
147         String JavaDoc challenge1 = "Digest realm=\"realm1\", nonce=\"abcde\"";
148         String JavaDoc challenge2 = "Digest realm=\"realm2\", nonce=\"123546\"";
149         UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
150         UsernamePasswordCredentials cred2 = new UsernamePasswordCredentials("uname2","password2");
151
152         FakeHttpMethod method = new FakeHttpMethod("/");
153         AuthScheme authscheme1 = new DigestScheme();
154         authscheme1.processChallenge(challenge1);
155         String JavaDoc response1 = authscheme1.authenticate(cred, method);
156         Map JavaDoc table = AuthChallengeParser.extractParams(response1);
157         assertEquals("username", table.get("username"));
158         assertEquals("realm1", table.get("realm"));
159         assertEquals("/", table.get("uri"));
160         assertEquals("abcde", table.get("nonce"));
161         assertEquals("786f500303eac1478f3c2865e676ed68", table.get("response"));
162
163         AuthScheme authscheme2 = new DigestScheme();
164         authscheme2.processChallenge(challenge2);
165         String JavaDoc response2 = authscheme2.authenticate(cred2, method);
166         table = AuthChallengeParser.extractParams(response2);
167         assertEquals("uname2", table.get("username"));
168         assertEquals("realm2", table.get("realm"));
169         assertEquals("/", table.get("uri"));
170         assertEquals("123546", table.get("nonce"));
171         assertEquals("0283edd9ef06a38b378b3b74661391e9", table.get("response"));
172     }
173
174     /**
175      * Test digest authentication using the MD5-sess algorithm.
176      */

177     public void testDigestAuthenticationMD5Sess() throws Exception JavaDoc {
178         // Example using Digest auth with MD5-sess
179

180         String JavaDoc realm="realm";
181         String JavaDoc username="username";
182         String JavaDoc password="password";
183         String JavaDoc nonce="e273f1776275974f1a120d8b92c5b3cb";
184
185         String JavaDoc challenge="Digest realm=\"" + realm + "\", "
186             + "nonce=\"" + nonce + "\", "
187             + "opaque=\"SomeString\", "
188             + "stale=false, "
189             + "algorithm=MD5-sess, "
190             + "qop=\"auth,auth-int\""; // we pass both but expect auth to be used
191

192         UsernamePasswordCredentials cred =
193             new UsernamePasswordCredentials(username, password);
194         FakeHttpMethod method = new FakeHttpMethod("/");
195
196         AuthScheme authscheme = new DigestScheme();
197         authscheme.processChallenge(challenge);
198         String JavaDoc response = authscheme.authenticate(cred, method);
199         assertTrue(response.indexOf("nc=00000001") > 0); // test for quotes
200
assertTrue(response.indexOf("qop=auth") > 0); // test for quotes
201
Map JavaDoc table = AuthChallengeParser.extractParams(response);
202         assertEquals(username, table.get("username"));
203         assertEquals(realm, table.get("realm"));
204         assertEquals("MD5-sess", table.get("algorithm"));
205         assertEquals("/", table.get("uri"));
206         assertEquals(nonce, table.get("nonce"));
207         assertEquals(1, Integer.parseInt((String JavaDoc) table.get("nc"),16));
208         assertTrue(null != table.get("cnonce"));
209         assertEquals("SomeString", table.get("opaque"));
210         assertEquals("auth", table.get("qop"));
211         //@TODO: add better check
212
assertTrue(null != table.get("response"));
213     }
214
215     /**
216      * Test digest authentication using the MD5-sess algorithm.
217      */

218     public void testDigestAuthenticationMD5SessNoQop() throws Exception JavaDoc {
219         // Example using Digest auth with MD5-sess
220

221         String JavaDoc realm="realm";
222         String JavaDoc username="username";
223         String JavaDoc password="password";
224         String JavaDoc nonce="e273f1776275974f1a120d8b92c5b3cb";
225
226         String JavaDoc challenge="Digest realm=\"" + realm + "\", "
227             + "nonce=\"" + nonce + "\", "
228             + "opaque=\"SomeString\", "
229             + "stale=false, "
230             + "algorithm=MD5-sess";
231
232         UsernamePasswordCredentials cred =
233             new UsernamePasswordCredentials(username, password);
234         FakeHttpMethod method = new FakeHttpMethod("/");
235
236         AuthScheme authscheme = new DigestScheme();
237         authscheme.processChallenge(challenge);
238         String JavaDoc response = authscheme.authenticate(cred, method);
239
240         Map JavaDoc table = AuthChallengeParser.extractParams(response);
241         assertEquals(username, table.get("username"));
242         assertEquals(realm, table.get("realm"));
243         assertEquals("MD5-sess", table.get("algorithm"));
244         assertEquals("/", table.get("uri"));
245         assertEquals(nonce, table.get("nonce"));
246         assertTrue(null == table.get("nc"));
247         assertEquals("SomeString", table.get("opaque"));
248         assertTrue(null == table.get("qop"));
249         //@TODO: add better check
250
assertTrue(null != table.get("response"));
251     }
252
253     /**
254      * Test digest authentication with invalud qop value
255      */

256     public void testDigestAuthenticationMD5SessInvalidQop() throws Exception JavaDoc {
257         // Example using Digest auth with MD5-sess
258

259         String JavaDoc realm="realm";
260         String JavaDoc username="username";
261         String JavaDoc password="password";
262         String JavaDoc nonce="e273f1776275974f1a120d8b92c5b3cb";
263
264         String JavaDoc challenge="Digest realm=\"" + realm + "\", "
265             + "nonce=\"" + nonce + "\", "
266             + "opaque=\"SomeString\", "
267             + "stale=false, "
268             + "algorithm=MD5-sess, "
269             + "qop=\"jakarta\""; // jakarta is an invalid qop value
270

271         UsernamePasswordCredentials cred =
272             new UsernamePasswordCredentials(username, password);
273         try {
274             AuthScheme authscheme = new DigestScheme();
275             authscheme.processChallenge(challenge);
276             fail("MalformedChallengeException exception expected due to invalid qop value");
277         } catch(MalformedChallengeException e) {
278         }
279     }
280
281     private class StaleNonceService implements HttpService {
282
283         public StaleNonceService() {
284             super();
285         }
286
287         public boolean process(final SimpleRequest request, final SimpleResponse response)
288             throws IOException JavaDoc
289         {
290             RequestLine requestLine = request.getRequestLine();
291             HttpVersion ver = requestLine.getHttpVersion();
292             Header auth = request.getFirstHeader("Authorization");
293             if (auth == null) {
294                 response.setStatusLine(ver, HttpStatus.SC_UNAUTHORIZED);
295                 response.addHeader(new Header("WWW-Authenticate",
296                         "Digest realm=\"realm1\", nonce=\"ABC123\""));
297                 response.setBodyString("Authorization required");
298                 return true;
299             } else {
300                 Map JavaDoc table = AuthChallengeParser.extractParams(auth.getValue());
301                 String JavaDoc nonce = (String JavaDoc)table.get("nonce");
302                 if (nonce.equals("ABC123")) {
303                     response.setStatusLine(ver, HttpStatus.SC_UNAUTHORIZED);
304                     response.addHeader(new Header("WWW-Authenticate",
305                             "Digest realm=\"realm1\", nonce=\"321CBA\", stale=\"true\""));
306                     response.setBodyString("Authorization required");
307                     return true;
308                 } else {
309                     response.setStatusLine(ver, HttpStatus.SC_OK);
310                     response.setBodyString("Authorization successful");
311                     return true;
312                 }
313             }
314         }
315     }
316
317     
318     public void testDigestAuthenticationWithStaleNonce() throws Exception JavaDoc {
319         // configure the server
320
SimpleHttpServer server = new SimpleHttpServer(); // use arbitrary port
321
server.setTestname(getName());
322         server.setHttpService(new StaleNonceService());
323
324         // configure the client
325
HttpClient client = new HttpClient();
326         client.getHostConfiguration().setHost(
327                 server.getLocalAddress(), server.getLocalPort(),
328                 Protocol.getProtocol("http"));
329         
330         client.getState().setCredentials(AuthScope.ANY,
331                 new UsernamePasswordCredentials("username","password"));
332         
333         FakeHttpMethod httpget = new FakeHttpMethod("/");
334         try {
335             client.executeMethod(httpget);
336         } finally {
337             httpget.releaseConnection();
338         }
339         assertNotNull(httpget.getStatusLine());
340         assertEquals(HttpStatus.SC_OK, httpget.getStatusLine().getStatusCode());
341         Map JavaDoc table = AuthChallengeParser.extractParams(
342                 httpget.getRequestHeader("Authorization").getValue());
343         assertEquals("username", table.get("username"));
344         assertEquals("realm1", table.get("realm"));
345         assertEquals("/", table.get("uri"));
346         assertEquals("321CBA", table.get("nonce"));
347         assertEquals("7f5948eefa115296e9279225041527b3", table.get("response"));
348         server.destroy();
349     }
350
351 }
352
Popular Tags