• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/AbstractAuthenticationHandler.java $
3  * $Revision: 673450 $
4  * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $
5  *
6  * ====================================================================
7  * Licensed to the Apache Software Foundation (ASF) under one
8  * or more contributor license agreements.  See the NOTICE file
9  * distributed with this work for additional information
10  * regarding copyright ownership.  The ASF licenses this file
11  * to you under the Apache License, Version 2.0 (the
12  * "License"); you may not use this file except in compliance
13  * with 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,
18  * software distributed under the License is distributed on an
19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20  * KIND, either express or implied.  See the License for the
21  * specific language governing permissions and limitations
22  * under the License.
23  * ====================================================================
24  *
25  * This software consists of voluntary contributions made by many
26  * individuals on behalf of the Apache Software Foundation.  For more
27  * information on the Apache Software Foundation, please see
28  * <http://www.apache.org/>.
29  *
30  */
31 
32 package org.apache.http.impl.client;
33 
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.Map;
39 
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.http.FormattedHeader;
43 import org.apache.http.Header;
44 import org.apache.http.HttpResponse;
45 import org.apache.http.auth.AuthScheme;
46 import org.apache.http.auth.AuthSchemeRegistry;
47 import org.apache.http.auth.AuthenticationException;
48 import org.apache.http.auth.MalformedChallengeException;
49 import org.apache.http.client.AuthenticationHandler;
50 import org.apache.http.client.protocol.ClientContext;
51 import org.apache.http.protocol.HTTP;
52 import org.apache.http.protocol.HttpContext;
53 import org.apache.http.util.CharArrayBuffer;
54 
55 /**
56  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
57  */
58 public abstract class AbstractAuthenticationHandler implements AuthenticationHandler {
59 
60     private final Log log = LogFactory.getLog(getClass());
61 
62     private static final List<String> DEFAULT_SCHEME_PRIORITY = Arrays.asList(new String[] {
63             "ntlm",
64             "digest",
65             "basic"
66     });
67 
AbstractAuthenticationHandler()68     public AbstractAuthenticationHandler() {
69         super();
70     }
71 
parseChallenges( final Header[] headers)72     protected Map<String, Header> parseChallenges(
73             final Header[] headers) throws MalformedChallengeException {
74 
75         Map<String, Header> map = new HashMap<String, Header>(headers.length);
76         for (Header header : headers) {
77             CharArrayBuffer buffer;
78             int pos;
79             if (header instanceof FormattedHeader) {
80                 buffer = ((FormattedHeader) header).getBuffer();
81                 pos = ((FormattedHeader) header).getValuePos();
82             } else {
83                 String s = header.getValue();
84                 if (s == null) {
85                     throw new MalformedChallengeException("Header value is null");
86                 }
87                 buffer = new CharArrayBuffer(s.length());
88                 buffer.append(s);
89                 pos = 0;
90             }
91             while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) {
92                 pos++;
93             }
94             int beginIndex = pos;
95             while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) {
96                 pos++;
97             }
98             int endIndex = pos;
99             String s = buffer.substring(beginIndex, endIndex);
100             map.put(s.toLowerCase(Locale.ENGLISH), header);
101         }
102         return map;
103     }
104 
getAuthPreferences()105     protected List<String> getAuthPreferences() {
106         return DEFAULT_SCHEME_PRIORITY;
107     }
108 
selectScheme( final Map<String, Header> challenges, final HttpResponse response, final HttpContext context)109     public AuthScheme selectScheme(
110             final Map<String, Header> challenges,
111             final HttpResponse response,
112             final HttpContext context) throws AuthenticationException {
113 
114         AuthSchemeRegistry registry = (AuthSchemeRegistry) context.getAttribute(
115                 ClientContext.AUTHSCHEME_REGISTRY);
116         if (registry == null) {
117             throw new IllegalStateException("AuthScheme registry not set in HTTP context");
118         }
119 
120         List<?> authPrefs = (List<?>) context.getAttribute(
121                 ClientContext.AUTH_SCHEME_PREF);
122         if (authPrefs == null) {
123             authPrefs = getAuthPreferences();
124         }
125 
126         if (this.log.isDebugEnabled()) {
127             this.log.debug("Authentication schemes in the order of preference: "
128                 + authPrefs);
129         }
130 
131         AuthScheme authScheme = null;
132         for (int i = 0; i < authPrefs.size(); i++) {
133             String id = (String) authPrefs.get(i);
134             Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH));
135 
136             if (challenge != null) {
137                 if (this.log.isDebugEnabled()) {
138                     this.log.debug(id + " authentication scheme selected");
139                 }
140                 try {
141                     authScheme = registry.getAuthScheme(id, response.getParams());
142                     break;
143                 } catch (IllegalStateException e) {
144                     if (this.log.isWarnEnabled()) {
145                         this.log.warn("Authentication scheme " + id + " not supported");
146                         // Try again
147                     }
148                 }
149             } else {
150                 if (this.log.isDebugEnabled()) {
151                     this.log.debug("Challenge for " + id + " authentication scheme not available");
152                     // Try again
153                 }
154             }
155         }
156         if (authScheme == null) {
157             // If none selected, something is wrong
158             throw new AuthenticationException(
159                 "Unable to respond to any of these challenges: "
160                     + challenges);
161         }
162         return authScheme;
163     }
164 
165 }
166