001: /*
002: * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/server/ProxyAuthRequestHandler.java,v 1.12 2004/11/28 15:44:39 olegk Exp $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient.server;
032:
033: import java.io.IOException;
034:
035: import org.apache.commons.httpclient.Credentials;
036: import org.apache.commons.httpclient.Header;
037: import org.apache.commons.httpclient.HttpStatus;
038: import org.apache.commons.httpclient.UsernamePasswordCredentials;
039: import org.apache.commons.httpclient.auth.BasicScheme;
040:
041: /**
042: * This request handler guards access to a proxy when used in a request handler
043: * chain. It checks the headers for valid credentials and performs the
044: * authentication handshake if necessary.
045: *
046: * @author Ortwin Glueck
047: * @author Oleg Kalnichevski
048: */
049: public class ProxyAuthRequestHandler implements HttpRequestHandler {
050:
051: private Credentials credentials = null;
052: private String realm = null;
053: private boolean keepalive = true;
054:
055: /**
056: * The proxy authenticate response header.
057: */
058: public static final String PROXY_AUTH_RESP = "Proxy-Authorization";
059:
060: /**
061: * TODO replace creds parameter with a class specific to an auth scheme
062: * encapsulating all required information for a specific scheme
063: *
064: * @param creds
065: */
066: public ProxyAuthRequestHandler(final Credentials creds,
067: final String realm, boolean keepalive) {
068: if (creds == null)
069: throw new IllegalArgumentException(
070: "Credentials may not be null");
071: this .credentials = creds;
072: this .keepalive = keepalive;
073: if (realm != null) {
074: this .realm = realm;
075: } else {
076: this .realm = "test";
077: }
078: }
079:
080: public ProxyAuthRequestHandler(final Credentials creds,
081: final String realm) {
082: this (creds, realm, true);
083: }
084:
085: public ProxyAuthRequestHandler(final Credentials creds) {
086: this (creds, null, true);
087: }
088:
089: public boolean processRequest(
090: final SimpleHttpServerConnection conn,
091: final SimpleRequest request) throws IOException {
092: Header clientAuth = request.getFirstHeader(PROXY_AUTH_RESP);
093: if (clientAuth != null && checkAuthorization(clientAuth)) {
094: return false;
095: } else {
096: SimpleResponse response = performBasicHandshake(conn,
097: request);
098: // Make sure the request body is fully consumed
099: request.getBodyBytes();
100: conn.writeResponse(response);
101: return true;
102: }
103: }
104:
105: //TODO add more auth schemes
106: private SimpleResponse performBasicHandshake(
107: final SimpleHttpServerConnection conn,
108: final SimpleRequest request) {
109:
110: SimpleResponse response = new SimpleResponse();
111: response.setStatusLine(request.getRequestLine()
112: .getHttpVersion(),
113: HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
114: if (!request.getRequestLine().getMethod().equalsIgnoreCase(
115: "HEAD")) {
116: response.setBodyString("unauthorized");
117: }
118: response.addHeader(new Header("Proxy-Authenticate",
119: "basic realm=\"" + this .realm + "\""));
120: if (this .keepalive) {
121: response.addHeader(new Header("Proxy-Connection",
122: "keep-alive"));
123: conn.setKeepAlive(true);
124: } else {
125: response.addHeader(new Header("Proxy-Connection", "close"));
126: conn.setKeepAlive(false);
127: }
128: return response;
129: }
130:
131: /**
132: * Checks if the credentials provided by the client match the required
133: * credentials
134: *
135: * @return true if the client is authorized, false if not.
136: * @param clientAuth
137: */
138: private boolean checkAuthorization(Header clientAuth) {
139: String expectedAuthString = BasicScheme
140: .authenticate(
141: (UsernamePasswordCredentials) credentials,
142: "ISO-8859-1");
143: return expectedAuthString.equals(clientAuth.getValue());
144: }
145:
146: }
|