1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/server/ProxyAuthRequestHandler.java,v 1.11 2004/11/13 12:21:28 olegk Exp $
3    * $Revision: 1.11 $
4    * $Date: 2004/11/13 12:21:28 $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  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.server;
31  
32  import java.io.IOException;
33  
34  import org.apache.commons.httpclient.Credentials;
35  import org.apache.commons.httpclient.Header;
36  import org.apache.commons.httpclient.HttpStatus;
37  import org.apache.commons.httpclient.UsernamePasswordCredentials;
38  import org.apache.commons.httpclient.auth.BasicScheme;
39  
40  /***
41   * This request handler guards access to a proxy when used in a request handler
42   * chain. It checks the headers for valid credentials and performs the
43   * authentication handshake if necessary.
44   * 
45   * @author Ortwin Glueck
46   * @author Oleg Kalnichevski
47   */
48  public class ProxyAuthRequestHandler implements HttpRequestHandler {
49      private Credentials credentials;
50  
51      /***
52       * The proxy authenticate response header.
53       */
54      public static final String PROXY_AUTH_RESP = "Proxy-Authorization";
55  
56      /***
57       * TODO replace creds parameter with a class specific to an auth scheme
58       * encapsulating all required information for a specific scheme
59       * 
60       * @param creds
61       */
62      public ProxyAuthRequestHandler(Credentials creds) {
63          if (creds == null)
64              throw new IllegalArgumentException("Credentials can not be null");
65          this.credentials = creds;
66      }
67  
68      public boolean processRequest(
69          final SimpleHttpServerConnection conn,
70          final SimpleRequest request) throws IOException
71      {
72          Header clientAuth = request.getFirstHeader(PROXY_AUTH_RESP);
73          if (clientAuth != null) {
74              return !checkAuthorization(clientAuth);
75          } else {
76              SimpleResponse response = performBasicHandshake(request);
77              // Make sure the request body is fully consumed
78              request.getBodyBytes();
79              conn.writeResponse(response);
80              return true;
81          }
82      }
83  
84      //TODO add more auth schemes
85      private SimpleResponse performBasicHandshake(final SimpleRequest request) { 
86          SimpleResponse response = new SimpleResponse();
87          response.setStatusLine(
88                  request.getRequestLine().getHttpVersion(),
89                  HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
90          response.addHeader(new Header("Proxy-Authenticate", "basic realm=test"));
91          //response.addHeader(new Header("Proxy-Connection", "Close"));
92          return response;
93      }
94  
95      /***
96       * Checks if the credentials provided by the client match the required
97       * credentials
98       * 
99       * @return true if the client is authorized, false if not.
100      * @param clientAuth
101      */
102     private boolean checkAuthorization(Header clientAuth) {
103         String expectedAuthString = BasicScheme.authenticate(
104             (UsernamePasswordCredentials)credentials,
105             "ISO-8859-1");
106         return expectedAuthString.equals(clientAuth.getValue());
107     }
108 
109 }