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