View Javadoc

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