    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/auth/TestNTLMAuth.java,v 1.2 2004/11/07 12:31:42 olegk Exp $
    3    * $Revision: 480424 $
    4    * $Date: 2006-11-29 06:56:49 +0100 (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;
    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 480424 2006-11-29 05:56:49Z bayard $
    57   */
    58  public class TestNTLMAuth extends HttpClientTestBase {
    59
    60      // ------------------------------------------------------------ Constructor
    61      public TestNTLMAuth(String testName) throws IOException {
    62          super(testName);
    63      }
    64
    65      // ------------------------------------------------------------------- Main
    66      public static void main(String args[]) {
    67          String[] testCaseName = { TestNTLMAuth.class.getName() };
    68          junit.textui.TestRunner.main(testCaseName);
    69      }
    70
    71      // ------------------------------------------------------- TestCase Methods
    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         // configure the client
    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 }