1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/BasicScheme.java $
3 * $Revision: 658430 $
4 * $Date: 2008-05-20 14:04:27 -0700 (Tue, 20 May 2008) $
5 *
6 * ====================================================================
7 *
8 *  Licensed to the Apache Software Foundation (ASF) under one or more
9 *  contributor license agreements.  See the NOTICE file distributed with
10 *  this work for additional information regarding copyright ownership.
11 *  The ASF licenses this file to You under the Apache License, Version 2.0
12 *  (the "License"); you may not use this file except in compliance with
13 *  the License.  You may obtain a copy of the License at
14 *
15 *      http://www.apache.org/licenses/LICENSE-2.0
16 *
17 *  Unless required by applicable law or agreed to in writing, software
18 *  distributed under the License is distributed on an "AS IS" BASIS,
19 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 *  See the License for the specific language governing permissions and
21 *  limitations under the License.
22 * ====================================================================
23 *
24 * This software consists of voluntary contributions made by many
25 * individuals on behalf of the Apache Software Foundation.  For more
26 * information on the Apache Software Foundation, please see
27 * <http://www.apache.org/>.
28 *
29 */
30
31package org.apache.http.impl.auth;
32
33import org.apache.commons.codec.binary.Base64;
34import org.apache.http.Header;
35import org.apache.http.HttpRequest;
36import org.apache.http.auth.AuthenticationException;
37import org.apache.http.auth.Credentials;
38import org.apache.http.auth.AUTH;
39import org.apache.http.auth.MalformedChallengeException;
40import org.apache.http.auth.params.AuthParams;
41import org.apache.http.message.BufferedHeader;
42import org.apache.http.util.CharArrayBuffer;
43import org.apache.http.util.EncodingUtils;
44
45/**
46 * <p>
47 * Basic authentication scheme as defined in RFC 2617.
48 * </p>
49 *
50 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
51 * @author Rodney Waldhoff
52 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
53 * @author Ortwin Glueck
54 * @author Sean C. Sullivan
55 * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
56 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
57 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
58 *
59 * @since 4.0
60 */
61
62public class BasicScheme extends RFC2617Scheme {
63
64    /** Whether the basic authentication process is complete */
65    private boolean complete;
66
67    /**
68     * Default constructor for the basic authetication scheme.
69     */
70    public BasicScheme() {
71        super();
72        this.complete = false;
73    }
74
75    /**
76     * Returns textual designation of the basic authentication scheme.
77     *
78     * @return <code>basic</code>
79     */
80    public String getSchemeName() {
81        return "basic";
82    }
83
84    /**
85     * Processes the Basic challenge.
86     *
87     * @param header the challenge header
88     *
89     * @throws MalformedChallengeException is thrown if the authentication challenge
90     * is malformed
91     */
92    @Override
93    public void processChallenge(
94            final Header header) throws MalformedChallengeException {
95        super.processChallenge(header);
96        this.complete = true;
97    }
98
99    /**
100     * Tests if the Basic authentication process has been completed.
101     *
102     * @return <tt>true</tt> if Basic authorization has been processed,
103     *   <tt>false</tt> otherwise.
104     */
105    public boolean isComplete() {
106        return this.complete;
107    }
108
109    /**
110     * Returns <tt>false</tt>. Basic authentication scheme is request based.
111     *
112     * @return <tt>false</tt>.
113     */
114    public boolean isConnectionBased() {
115        return false;
116    }
117
118    /**
119     * Produces basic authorization header for the given set of {@link Credentials}.
120     *
121     * @param credentials The set of credentials to be used for athentication
122     * @param request The request being authenticated
123     * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials
124     *         are not valid or not applicable for this authentication scheme
125     * @throws AuthenticationException if authorization string cannot
126     *   be generated due to an authentication failure
127     *
128     * @return a basic authorization string
129     */
130    public Header authenticate(
131            final Credentials credentials,
132            final HttpRequest request) throws AuthenticationException {
133
134        if (credentials == null) {
135            throw new IllegalArgumentException("Credentials may not be null");
136        }
137        if (request == null) {
138            throw new IllegalArgumentException("HTTP request may not be null");
139        }
140
141        String charset = AuthParams.getCredentialCharset(request.getParams());
142        return authenticate(credentials, charset, isProxy());
143    }
144
145    /**
146     * Returns a basic <tt>Authorization</tt> header value for the given
147     * {@link Credentials} and charset.
148     *
149     * @param credentials The credentials to encode.
150     * @param charset The charset to use for encoding the credentials
151     *
152     * @return a basic authorization header
153     */
154    public static Header authenticate(
155            final Credentials credentials,
156            final String charset,
157            boolean proxy) {
158        if (credentials == null) {
159            throw new IllegalArgumentException("Credentials may not be null");
160        }
161        if (charset == null) {
162            throw new IllegalArgumentException("charset may not be null");
163        }
164
165        StringBuilder tmp = new StringBuilder();
166        tmp.append(credentials.getUserPrincipal().getName());
167        tmp.append(":");
168        tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());
169
170        byte[] base64password = Base64.encodeBase64(
171                EncodingUtils.getBytes(tmp.toString(), charset));
172
173        CharArrayBuffer buffer = new CharArrayBuffer(32);
174        if (proxy) {
175            buffer.append(AUTH.PROXY_AUTH_RESP);
176        } else {
177            buffer.append(AUTH.WWW_AUTH_RESP);
178        }
179        buffer.append(": Basic ");
180        buffer.append(base64password, 0, base64password.length);
181
182        return new BufferedHeader(buffer);
183    }
184
185}
186