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.annotation.NotThreadSafe;
36  import org.apache.http.auth.AUTH;
37  import org.apache.http.auth.AuthenticationException;
38  import org.apache.http.auth.ChallengeState;
39  import org.apache.http.auth.ContextAwareAuthScheme;
40  import org.apache.http.auth.Credentials;
41  import org.apache.http.auth.InvalidCredentialsException;
42  import org.apache.http.auth.MalformedChallengeException;
43  import org.apache.http.message.BufferedHeader;
44  import org.apache.http.protocol.BasicHttpContext;
45  import org.apache.http.protocol.HttpContext;
46  import org.apache.http.util.Args;
47  import org.apache.http.util.CharArrayBuffer;
48  import org.apache.http.util.EncodingUtils;
49  
50  /**
51   * Basic authentication scheme as defined in RFC 2617.
52   *
53   * @since 4.0
54   */
55  @NotThreadSafe
56  public class BasicScheme extends RFC2617Scheme {
57  
58      private final Base64 base64codec;
59      /** Whether the basic authentication process is complete */
60      private boolean complete;
61  
62      /**
63       * @since 4.3
64       */
65      public BasicScheme(final Charset credentialsCharset) {
66          super(credentialsCharset);
67          this.base64codec = new Base64(0);
68          this.complete = false;
69      }
70  
71      /**
72       * Creates an instance of <tt>BasicScheme</tt> with the given challenge
73       * state.
74       *
75       * @since 4.2
76       *
77       * @deprecated (4.3) do not use.
78       */
79      @Deprecated
80      public BasicScheme(final ChallengeState challengeState) {
81          super(challengeState);
82          this.base64codec = new Base64(0);
83      }
84  
85      public BasicScheme() {
86          this(Consts.ASCII);
87      }
88  
89      /**
90       * Returns textual designation of the basic authentication scheme.
91       *
92       * @return <code>basic</code>
93       */
94      public String getSchemeName() {
95          return "basic";
96      }
97  
98      /**
99       * Processes the Basic challenge.
100      *
101      * @param header the challenge header
102      *
103      * @throws MalformedChallengeException is thrown if the authentication challenge
104      * is malformed
105      */
106     @Override
107     public void processChallenge(
108             final Header header) throws MalformedChallengeException {
109         super.processChallenge(header);
110         this.complete = true;
111     }
112 
113     /**
114      * Tests if the Basic authentication process has been completed.
115      *
116      * @return <tt>true</tt> if Basic authorization has been processed,
117      *   <tt>false</tt> otherwise.
118      */
119     public boolean isComplete() {
120         return this.complete;
121     }
122 
123     /**
124      * Returns <tt>false</tt>. Basic authentication scheme is request based.
125      *
126      * @return <tt>false</tt>.
127      */
128     public boolean isConnectionBased() {
129         return false;
130     }
131 
132     /**
133      * @deprecated (4.2) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)}
134      */
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 InvalidCredentialsException if authentication credentials are not
147      *   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 byte[] base64password = base64codec.encode(
167                 EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request)));
168 
169         final CharArrayBuffer buffer = new CharArrayBuffer(32);
170         if (isProxy()) {
171             buffer.append(AUTH.PROXY_AUTH_RESP);
172         } else {
173             buffer.append(AUTH.WWW_AUTH_RESP);
174         }
175         buffer.append(": Basic ");
176         buffer.append(base64password, 0, base64password.length);
177 
178         return new BufferedHeader(buffer);
179     }
180 
181     /**
182      * Returns a basic <tt>Authorization</tt> header value for the given
183      * {@link Credentials} and charset.
184      *
185      * @param credentials The credentials to encode.
186      * @param charset The charset to use for encoding the credentials
187      *
188      * @return a basic authorization header
189      *
190      * @deprecated (4.3) use {@link #authenticate(Credentials, HttpRequest, HttpContext)}.
191      */
192     @Deprecated
193     public static Header authenticate(
194             final Credentials credentials,
195             final String charset,
196             final boolean proxy) {
197         Args.notNull(credentials, "Credentials");
198         Args.notNull(charset, "charset");
199 
200         final StringBuilder tmp = new StringBuilder();
201         tmp.append(credentials.getUserPrincipal().getName());
202         tmp.append(":");
203         tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());
204 
205         final byte[] base64password = Base64.encodeBase64(
206                 EncodingUtils.getBytes(tmp.toString(), charset), false);
207 
208         final CharArrayBuffer buffer = new CharArrayBuffer(32);
209         if (proxy) {
210             buffer.append(AUTH.PROXY_AUTH_RESP);
211         } else {
212             buffer.append(AUTH.WWW_AUTH_RESP);
213         }
214         buffer.append(": Basic ");
215         buffer.append(base64password, 0, base64password.length);
216 
217         return new BufferedHeader(buffer);
218     }
219 
220 }