Author: dkulp
Date: Fri Jan 23 23:06:21 2009
New Revision: 737237
URL: http://svn.apache.org/viewvc?rev=737237&view=rev
Log:
Support for digest auth. Changes API's a bit, will add to migration guide.
Added:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
(with props)
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java
(contents, props changed)
- copied, changed from r737123,
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpBasicAuthSupplier.java
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java
(contents, props changed)
- copied, changed from r737123,
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpBasicAuthSupplierBeanDefinitionParser.java
Removed:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpBasicAuthSupplier.java
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpBasicAuthSupplierBeanDefinitionParser.java
Modified:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpConduitBeanDefinitionParser.java
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/NamespaceHandler.java
cxf/trunk/rt/transports/http/src/main/resources/schemas/configuration/http-conf.xsd
cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/http/HTTPConduitTest.java
Added:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java?rev=737237&view=auto
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
(added)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
Fri Jan 23 23:06:21 2009
@@ -0,0 +1,227 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.transport.http;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.message.Message;
+
+/**
+ *
+ */
+public class DigestAuthSupplier extends HttpAuthSupplier {
+ private static final char[] HEXADECIMAL = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'
+ };
+ private static final MessageDigest MD5_HELPER;
+ static {
+ MessageDigest md = null;
+ try {
+ md = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ md = null;
+ }
+ MD5_HELPER = md;
+ }
+
+ Map<URL, DigestInfo> authInfo = new ConcurrentHashMap<URL, DigestInfo>();
+
+ @Override
+ public String getAuthorizationForRealm(HTTPConduit conduit, URL currentURL,
+ Message message,
+ String realm, String fullHeader) {
+ if (fullHeader.startsWith("Digest ")) {
+ Map<String, String> map = new HashMap<String, String>();
+ fullHeader = fullHeader.substring(7);
+ StringTokenizer tok = new StringTokenizer(fullHeader, ",=");
+ while (tok.hasMoreTokens()) {
+ String key = tok.nextToken().trim();
+ String value = tok.nextToken().trim();
+ if (value.charAt(0) == '"') {
+ value = value.substring(1, value.length() - 1);
+ }
+ map.put(key, value);
+ }
+ if ("auth".equals(map.get("qop"))
+ || !map.containsKey("qop")) {
+ DigestInfo di = new DigestInfo();
+ di.qop = map.get("qop");
+ di.realm = map.get("realm");
+ di.nonce = map.get("nonce");
+ di.opaque = map.get("opaque");
+ if (map.containsKey("algorithm")) {
+ di.algorithm = map.get("algorithm");
+ }
+ if (map.containsKey("charset")) {
+ di.charset = map.get("charset");
+ }
+ di.method = (String)message.get(Message.HTTP_REQUEST_METHOD);
+ if (di.method == null) {
+ di.method = "POST";
+ }
+ authInfo.put(currentURL, di);
+ return di.generateAuth(currentURL.getFile(),
+ getUsername(message),
+ getPassword(message));
+ }
+
+ }
+ return null;
+ }
+ @Override
+ public String getPreemptiveAuthorization(HTTPConduit conduit, URL
currentURL, Message message) {
+ DigestInfo di = authInfo.get(currentURL);
+ if (di != null) {
+ return di.generateAuth(currentURL.getFile(),
+ getUsername(message),
+ getPassword(message));
+ }
+ return null;
+ }
+
+ private String getPassword(Message message) {
+ AuthorizationPolicy policy
+ =
(AuthorizationPolicy)message.getContextualProperty(AuthorizationPolicy.class.getName());
+ if (policy != null) {
+ return policy.getUserName();
+ }
+ return null;
+ }
+
+ private String getUsername(Message message) {
+ AuthorizationPolicy policy
+ =
(AuthorizationPolicy)message.getContextualProperty(AuthorizationPolicy.class.getName());
+ if (policy != null) {
+ return policy.getPassword();
+ }
+ return null;
+ }
+
+
+ class DigestInfo {
+ String qop;
+ String realm;
+ String nonce;
+ String opaque;
+ int nc;
+ String algorithm = "MD5";
+ String charset = "ISO-8859-1";
+ String method = "POST";
+
+ synchronized String generateAuth(String uri, String username, String
password) {
+ try {
+ StringBuilder builder = new StringBuilder("Digest qop=auth,
realm=\"");
+ nc++;
+ String ncstring = Integer.toString(nc);
+ while (ncstring.length() < 8) {
+ ncstring = "0" + ncstring;
+ }
+ String cnonce = createCnonce();
+
+ String digAlg = algorithm;
+ if (digAlg.equalsIgnoreCase("MD5-sess")) {
+ digAlg = "MD5";
+ }
+ MessageDigest digester = MessageDigest.getInstance(digAlg);
+ String a1 = username + ":" + realm + ":" + password;
+ if ("MD5-sess".equalsIgnoreCase(algorithm)) {
+ algorithm = "MD5";
+ String tmp2 =
encode(digester.digest(a1.getBytes(charset)));
+ StringBuilder tmp3 = new StringBuilder(
+ tmp2.length() + nonce.length() + cnonce.length() +
2);
+ tmp3.append(tmp2);
+ tmp3.append(':');
+ tmp3.append(nonce);
+ tmp3.append(':');
+ tmp3.append(cnonce);
+ a1 = tmp3.toString();
+ }
+ String hasha1 = encode(digester.digest(a1.getBytes(charset)));
+ String a2 = method + ":" + uri;
+ String hasha2 =
encode(digester.digest(a2.getBytes("US-ASCII")));
+ String serverDigestValue = null;
+ if (qop == null) {
+ serverDigestValue = hasha1 + ":" + nonce + ":" + hasha2;
+ } else {
+ serverDigestValue = hasha1 + ":" + nonce + ":" + ncstring
+ ":" + cnonce + ":"
+ + qop + ":" + hasha2;
+ }
+ serverDigestValue =
encode(digester.digest(serverDigestValue.getBytes("US-ASCII")));
+ builder.append(realm).append("\", opaque=\"")
+ .append(opaque)
+ .append("\", nonce=\"")
+ .append(nonce)
+ .append("\", uri=\"")
+ .append(uri)
+ .append("\", username=\"")
+ .append(username)
+ .append("\", nc=")
+ .append(ncstring)
+ .append(", cnonce=\"")
+ .append(cnonce)
+ .append("\", response=\"")
+ .append(serverDigestValue)
+ .append("\"");
+
+ return builder.toString();
+ } catch (RuntimeException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+
+ }
+
+ public static String createCnonce() throws UnsupportedEncodingException {
+ String cnonce = Long.toString(System.currentTimeMillis());
+ return encode(MD5_HELPER.digest(cnonce.getBytes("US-ASCII")));
+ }
+
+ /**
+ * Encodes the 128 bit (16 bytes) MD5 digest into a 32 characters long
+ * <CODE>String</CODE> according to RFC 2617.
+ *
+ * @param binaryData array containing the digest
+ * @return encoded MD5, or <CODE>null</CODE> if encoding failed
+ */
+ private static String encode(byte[] binaryData) {
+ int n = binaryData.length;
+ char[] buffer = new char[n * 2];
+ for (int i = 0; i < n; i++) {
+ int low = binaryData[i] & 0x0f;
+ int high = (binaryData[i] & 0xf0) >> 4;
+ buffer[i * 2] = HEXADECIMAL[high];
+ buffer[(i * 2) + 1] = HEXADECIMAL[low];
+ }
+
+ return new String(buffer);
+ }
+
+}
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=737237&r1=737236&r2=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
(original)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
Fri Jan 23 23:06:21 2009
@@ -241,9 +241,9 @@
private MessageTrustDecider trustDecider;
/**
- * This field contains the HttpBasicAuthSupplier.
+ * This field contains the HttpAuthSupplier.
*/
- private HttpBasicAuthSupplier basicAuthSupplier;
+ private HttpAuthSupplier authSupplier;
/**
* This boolean signfies that that finalizeConfig is called, which is
@@ -360,9 +360,9 @@
trustDecider = endpointInfo.getTraversedExtensor(
null, MessageTrustDecider.class);
}
- if (this.basicAuthSupplier == null) {
- basicAuthSupplier = endpointInfo.getTraversedExtensor(
- null, HttpBasicAuthSupplier.class);
+ if (this.authSupplier == null) {
+ authSupplier = endpointInfo.getTraversedExtensor(
+ null, HttpAuthSupplier.class);
}
if (trustDecider == null) {
if (LOG.isLoggable(Level.FINE)) {
@@ -381,18 +381,18 @@
+ "'");
}
}
- if (basicAuthSupplier == null) {
+ if (authSupplier == null) {
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE,
- "No Basic Auth Supplier configured for Conduit '"
+ "No Auth Supplier configured for Conduit '"
+ getConduitName() + "'");
}
} else {
if (LOG.isLoggable(Level.FINE)) {
- LOG.log(Level.FINE, "HttpBasicAuthSupplier of class '"
- + basicAuthSupplier.getClass().getName()
+ LOG.log(Level.FINE, "HttpAuthSupplier of class '"
+ + authSupplier.getClass().getName()
+ "' with logical name of '"
- + basicAuthSupplier.getLogicalName()
+ + authSupplier.getLogicalName()
+ "' has been configured for Conduit '"
+ getConduitName()
+ "'");
@@ -477,8 +477,6 @@
// with the Conduit.
URL currentURL = setupURL(message);
- HttpBasicAuthSupplier.UserPass userPass = null;
-
// The need to cache the request is off by default
boolean needToCacheRequest = false;
@@ -519,13 +517,16 @@
int chunkThreshold = 0;
// We must cache the request if we have basic auth supplier
// without preemptive basic auth.
- if (basicAuthSupplier != null) {
- userPass = basicAuthSupplier.getPreemptiveUserPass(
- getConduitName(), currentURL, message);
- needToCacheRequest = userPass == null;
- LOG.log(Level.INFO,
- "Basic Auth Supplier, but no Premeptive User Pass."
- + " We must cache request.");
+ if (authSupplier != null) {
+ String auth = authSupplier.getPreemptiveAuthorization(
+ this, currentURL, message);
+ if (auth == null) {
+ needToCacheRequest = true;
+ isChunking = false;
+ LOG.log(Level.INFO,
+ "Auth Supplier, but no Premeptive User Pass."
+ + " We must cache request.");
+ }
}
if (getClient().isAutoRedirect()) {
needToCacheRequest = true;
@@ -1064,7 +1065,7 @@
* <p>
* The precedence is as follows:
* 1. AuthorizationPolicy that is set on the Message, if exists.
- * 2. Preemptive UserPass from BasicAuthSupplier, if exists.
+ * 2. Authorization from AuthSupplier, if exists.
* 3. AuthorizationPolicy set/configured for conduit.
*
* REVISIT: Since the AuthorizationPolicy is set on the message by class,
then
@@ -1080,25 +1081,28 @@
Map<String, List<String>> headers
) {
AuthorizationPolicy authPolicy = getAuthorization();
+ AuthorizationPolicy newPolicy = message.get(AuthorizationPolicy.class);
- HttpBasicAuthSupplier.UserPass userpass = null;
- if (basicAuthSupplier != null) {
- userpass = basicAuthSupplier.getPreemptiveUserPass(
- getConduitName(), url, message);
+ String authString = null;
+ if (authSupplier != null
+ && (newPolicy == null
+ || (!"Basic".equals(newPolicy.getAuthorizationType())
+ && newPolicy.getAuthorization() == null))) {
+ authString = authSupplier.getPreemptiveAuthorization(
+ this, url, message);
+ if (authString != null) {
+ headers.put("Authorization",
+ createMutableList(authString));
+ return;
+ }
}
-
- AuthorizationPolicy newPolicy = message.get(AuthorizationPolicy.class);
String userName = null;
String passwd = null;
if (null != newPolicy) {
userName = newPolicy.getUserName();
passwd = newPolicy.getPassword();
}
- if (userName == null
- && userpass != null) {
- userName = userpass.getUserid();
- passwd = userpass.getPassword();
- }
+
if (userName == null
&& authPolicy != null && authPolicy.isSetUserName()) {
userName = authPolicy.getUserName();
@@ -1339,21 +1343,16 @@
}
/**
- * This method gets the Basic Auth Supplier that was set/configured for
this
+ * This method gets the Auth Supplier that was set/configured for this
* HTTPConduit.
- * @return The Basic Auth Supplier or null.
+ * @return The Auth Supplier or null.
*/
- public HttpBasicAuthSupplier getBasicAuthSupplier() {
- return this.basicAuthSupplier;
+ public HttpAuthSupplier getAuthSupplier() {
+ return this.authSupplier;
}
- /**
- * This method sets the Trust Decider for this HTTP Conduit.
- * Using this method overrides any trust decider configured for this
- * HTTPConduit.
- */
- public void setBasicAuthSupplier(HttpBasicAuthSupplier supplier) {
- this.basicAuthSupplier = supplier;
+ public void setAuthSupplier(HttpAuthSupplier supplier) {
+ this.authSupplier = supplier;
}
/**
@@ -1521,8 +1520,13 @@
// If we don't have a dynamic supply of user pass, then
// we don't retransmit. We just die with a Http 401 response.
- if (basicAuthSupplier == null) {
- return connection;
+ if (authSupplier == null) {
+ String auth = connection.getHeaderField("WWW-Authenticate");
+ if (auth.startsWith("Digest ")) {
+ authSupplier = new DigestAuthSupplier();
+ } else {
+ return connection;
+ }
}
URL currentURL = connection.getURL();
@@ -1554,9 +1558,9 @@
+ "\"");
}
- HttpBasicAuthSupplier.UserPass up =
- basicAuthSupplier.getUserPassForRealm(
- getConduitName(), currentURL, message, realm);
+ String up =
+ authSupplier.getAuthorizationForRealm(
+ this, currentURL, message, realm,
connection.getHeaderField("WWW-Authenticate"));
// No user pass combination. We give up.
if (up == null) {
@@ -1567,9 +1571,8 @@
authURLs.add(currentURL.toString() + realm);
Map<String, List<String>> headers = getSetProtocolHeaders(message);
-
- setBasicAuthHeader(up.getUserid(), up.getPassword(), headers);
-
+ headers.put("Authorization",
+ createMutableList(up));
return retransmit(
connection, currentURL, message, cachedStream);
}
@@ -1673,8 +1676,15 @@
List<String> auth = headers.get("WWW-Authenticate");
if (auth != null) {
for (String a : auth) {
- if (a.startsWith("Basic realm=")) {
- return a.substring(a.indexOf("=") + 1);
+ int idx = a.indexOf("realm=");
+ if (idx != -1) {
+ a = a.substring(idx + 6);
+ if (a.charAt(0) == '"') {
+ a = a.substring(1, a.indexOf('"', 1));
+ } else if (a.contains(",")) {
+ a = a.substring(0, a.indexOf(','));
+ }
+ return a;
}
}
}
Copied:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java
(from r737123,
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpBasicAuthSupplier.java)
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java?p2=cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java&p1=cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpBasicAuthSupplier.java&r1=737123&r2=737237&rev=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpBasicAuthSupplier.java
(original)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java
Fri Jan 23 23:06:21 2009
@@ -24,27 +24,27 @@
import org.apache.cxf.message.Message;
/**
- * This abstract class is extended by developers who need HTTP Basic Auth
- * functionality on the client side. It supplies userid and password
- * combinations to an HTTPConduit.
+ * This abstract class is extended by developers who need HTTP Auth
+ * functionality on the client side. It supplies Authorization
+ * information to an HTTPConduit.
* <p>
- * The HTTPConduit will make a call to getPreemptiveUserPass before
+ * The HTTPConduit will make a call to getPreemptiveAuthorization before
* an HTTP request is made. The HTTPConduit will call on
- * getUserPassForRealm upon getting a 401 HTTP Response with a
+ * getAuthorizationForRealm upon getting a 401 HTTP Response with a
* "WWW-Authenticate: Basic realm=????" header.
* <p>
- * A HTTPConduit keeps a reference to this HttpBasicAuthSupplier for the life
+ * A HTTPConduit keeps a reference to this HttpAuthSupplier for the life
* of the HTTPConduit, unless changed out by dynamic configuration.
- * Therefore, an implementation of this HttpBasicAuthSupplier may maintain
+ * Therefore, an implementation of this HttpAuthSupplier may maintain
* state for subsequent calls.
* <p>
- * For instance, an implemenation may not provide a UserPass preemptively for
+ * For instance, an implementation may not provide a Authorization
preemptively for
* a particular URL and decide to get the realm information from
- * a 401 response in which the HTTPConduit will call getUserPassForReam for
- * that URL. Then this implementation may provide the UserPass for this
- * particular URL preemptively for subsequent calls to getPreemptiveUserPass.
+ * a 401 response in which the HTTPConduit will call getAuthorizationForReam
for
+ * that URL. Then this implementation may provide the Authorization for this
+ * particular URL preemptively for subsequent calls to
getPreemptiveAuthorization.
*/
-public abstract class HttpBasicAuthSupplier {
+public abstract class HttpAuthSupplier {
/**
* This field contains the logical name of this HttpBasicAuthSuppler.
@@ -58,7 +58,7 @@
* The default constructor assigns the class name as the LogicalName.
*
*/
- protected HttpBasicAuthSupplier() {
+ protected HttpAuthSupplier() {
logicalName = this.getClass().getName();
}
@@ -67,7 +67,7 @@
*
* @param name The Logical Name.
*/
- protected HttpBasicAuthSupplier(String name) {
+ protected HttpAuthSupplier(String name) {
logicalName = name;
}
@@ -78,75 +78,20 @@
return logicalName;
}
- /**
- * This class is used to return the values of the
- * userid and password used in the HTTP Authorization
- * Header.
- */
- public static final class UserPass {
- private final String userid;
- private final String password;
-
- /**
- * This constructor forms the userid and password pair for
- * the HTTP Authorization header.
- *
- * @param user The userid that will be returned from getUserid().
- * This argument must not contain a colon (":"). If
- * it does, it will throw an IllegalArgumentException.
- *
- * @param pass The password that will be returned from getPassword().
- */
- UserPass(String user, String pass) {
- if (user.contains(":")) {
- throw new IllegalArgumentException(
- "The argument \"user\" cannot contain ':'.");
- }
- userid = user;
- password = pass;
- }
- /**
- * This method returns the userid.
- */
- public String getUserid() {
- return userid;
- }
- /**
- * This method returns the password.
- */
- public String getPassword() {
- return password;
- }
- }
/**
- * This method is used by extensions of this class to create
- * a UserPass to return.
- * @param userid The userid that will be returned from getUserid().
- * This argument must not contain a colon (":"). If
- * it does, it will throw an IllegalArgumentException.
- * @param password The password that will be returned from getPassword().
- * @return
- */
- protected UserPass createUserPass(
- final String userid,
- final String password
- ) {
- return new UserPass(userid, password);
- }
- /**
* The HTTPConduit makes a call to this method before connecting
* to the server behind a particular URL. If this implementation does not
- * have a UserPass for this URL, it should return null.
+ * have a Authorization for this URL, it should return null.
*
- * @param conduitName The HTTPConduit making the call.
+ * @param conduit The HTTPConduit making the call.
* @param currentURL The URL to which the request is to be made.
* @param message The CXF Message.
*
- * @return This method returns null if no UserPass is available.
+ * @return This method returns null if no Authorization is available.
*/
- public abstract UserPass getPreemptiveUserPass(
- String conduitName,
+ public abstract String getPreemptiveAuthorization(
+ HTTPConduit conduit,
URL currentURL,
Message message);
@@ -154,22 +99,24 @@
* The HTTPConduit makes a call to this method if it
* receives a 401 response to a particular URL for
* a given message. The realm information is taken
- * from the "WWW-Authenticate: Basic realm=?????"
+ * from the "WWW-Authenticate: ???? realm=?????"
* header. The current message may be retransmitted
- * if this call returns a UserPass. The current message will
- * fail with a 401 if null is returned. If no UserPass is available
+ * if this call returns a Authorization. The current message will
+ * fail with a 401 if null is returned. If no Authorization is available
* for this particular URL, realm, and message, then null
* should be returned.
*
- * @param conduitName The name of the conduit making the call.
+ * @param conduit The conduit making the call.
* @param currentURL The current URL from which the reponse came.
* @param message The CXF Message.
* @param realm The realm extraced from the basic auth header.
+ * @param fullHeader The full WWW-Authenticate header
* @return
*/
- public abstract UserPass getUserPassForRealm(
- String conduitName,
+ public abstract String getAuthorizationForRealm(
+ HTTPConduit conduit,
URL currentURL,
Message message,
- String realm);
+ String realm,
+ String fullHeader);
}
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthSupplier.java
------------------------------------------------------------------------------
svn:mergeinfo =
Copied:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java
(from r737123,
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpBasicAuthSupplierBeanDefinitionParser.java)
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java?p2=cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java&p1=cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpBasicAuthSupplierBeanDefinitionParser.java&r1=737123&r2=737237&rev=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpBasicAuthSupplierBeanDefinitionParser.java
(original)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java
Fri Jan 23 23:06:21 2009
@@ -22,9 +22,9 @@
import org.w3c.dom.Element;
import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
-import org.apache.cxf.transport.http.HttpBasicAuthSupplier;
+import org.apache.cxf.transport.http.HttpAuthSupplier;
-public class HttpBasicAuthSupplierBeanDefinitionParser extends
+public class HttpAuthSupplierBeanDefinitionParser extends
AbstractBeanDefinitionParser {
@Override
@@ -33,7 +33,7 @@
}
@Override
protected Class getBeanClass(Element arg0) {
- return HttpBasicAuthSupplier.class;
+ return HttpAuthSupplier.class;
}
}
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpAuthSupplierBeanDefinitionParser.java
------------------------------------------------------------------------------
svn:mergeinfo =
Modified:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpConduitBeanDefinitionParser.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpConduitBeanDefinitionParser.java?rev=737237&r1=737236&r2=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpConduitBeanDefinitionParser.java
(original)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/HttpConduitBeanDefinitionParser.java
Fri Jan 23 23:06:21 2009
@@ -34,7 +34,7 @@
import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.transport.http.HTTPConduit;
-import org.apache.cxf.transport.http.HttpBasicAuthSupplier;
+import org.apache.cxf.transport.http.HttpAuthSupplier;
import org.apache.cxf.transport.http.MessageTrustDecider;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -86,7 +86,7 @@
if ("trustDecider".equals(elementName)) {
mapBeanOrClassElement((Element)n, bean,
MessageTrustDecider.class);
} else if ("basicAuthSupplier".equals(elementName)) {
- mapBeanOrClassElement((Element)n, bean,
HttpBasicAuthSupplier.class);
+ mapBeanOrClassElement((Element)n, bean,
HttpAuthSupplier.class);
} else if ("tlsClientParameters".equals(elementName)) {
mapTLSClientParameters((Element)n, bean);
}
Modified:
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/NamespaceHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/NamespaceHandler.java?rev=737237&r1=737236&r2=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/NamespaceHandler.java
(original)
+++
cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/spring/NamespaceHandler.java
Fri Jan 23 23:06:21 2009
@@ -26,8 +26,8 @@
new HttpConduitBeanDefinitionParser());
registerBeanDefinitionParser("trustDecider",
new MessageTrustDeciderBeanDefinitionParser());
- registerBeanDefinitionParser("basicAuthSupplier",
- new HttpBasicAuthSupplierBeanDefinitionParser());
+ registerBeanDefinitionParser("authSupplier",
+ new HttpAuthSupplierBeanDefinitionParser());
registerBeanDefinitionParser("destination",
new HttpDestinationBeanDefinitionParser());
}
Modified:
cxf/trunk/rt/transports/http/src/main/resources/schemas/configuration/http-conf.xsd
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/resources/schemas/configuration/http-conf.xsd?rev=737237&r1=737236&r2=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/main/resources/schemas/configuration/http-conf.xsd
(original)
+++
cxf/trunk/rt/transports/http/src/main/resources/schemas/configuration/http-conf.xsd
Fri Jan 23 23:06:21 2009
@@ -48,7 +48,7 @@
<xs:element name="proxyAuthorization"
type="sec:ProxyAuthorizationPolicy"/>
<xs:element name="tlsClientParameters" type="sec:TLSClientParametersType"/>
<xs:element name="trustDecider" type="cxf-beans:ClassOrBeanType"/>
- <xs:element name="basicAuthSupplier" type="cxf-beans:ClassOrBeanType"/>
+ <xs:element name="authSupplier" type="cxf-beans:ClassOrBeanType"/>
<xs:element name="conduit">
@@ -92,15 +92,15 @@
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element ref="http-conf:basicAuthSupplier"
+ <xs:element ref="http-conf:authSupplier"
minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
Holds the bean reference or class name
- of an object that supplies Basic Auth information
+ of an object that supplies Auth information
both preemptively and in response to a 401 HTTP
Challenge. This class must extend the abstract class
- org.apache.cxf.transport.http.BasicAuthSupplier.
+ org.apache.cxf.transport.http.HttpAuthSupplier.
</xs:documentation>
</xs:annotation>
</xs:element>
Modified:
cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java?rev=737237&r1=737236&r2=737237&view=diff
==============================================================================
---
cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java
(original)
+++
cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java
Fri Jan 23 23:06:21 2009
@@ -82,13 +82,15 @@
* This test class is a Basic Auth Supplier with a
* preemptive UserPass.
*/
- class BasicAuthSupplier extends HttpBasicAuthSupplier {
- public UserPass getPreemptiveUserPass(
- String conduitName, URL url, Message m) {
- return createUserPass("Gandalf", "staff");
+ class BasicAuthSupplier extends HttpAuthSupplier {
+ public String getPreemptiveAuthorization(
+ HTTPConduit conduit, URL url, Message m) {
+ String userpass = "Gandalf:staff";
+ String token = Base64Utility.encode(userpass.getBytes());
+ return "Basic " + token;
}
- public UserPass getUserPassForRealm(
- String conduitName, URL url, Message m, String r) {
+ public String getAuthorizationForRealm(
+ HTTPConduit conduit, URL url, Message m, String r, String fh) {
return null;
}
}
@@ -207,7 +209,7 @@
headers.get("Authorization").get(0));
// Setting a Basic Auth User Pass should override
- conduit.setBasicAuthSupplier(new BasicAuthSupplier());
+ conduit.setAuthSupplier(new BasicAuthSupplier());
message = getNewMessage();
// Test Call
@@ -216,14 +218,17 @@
headers =
CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS));
- assertEquals("Unexpected Authorization Token",
+ String head = headers.get("Authorization").get(0);
+ assertEquals("Unexpected Authorization Token: "
+ + new String(Base64Utility.decode(head.substring(6))),
"Basic " + Base64Utility.encode("Gandalf:staff".getBytes()),
- headers.get("Authorization").get(0));
+ head);
// Setting authorization policy on the message should override all.
AuthorizationPolicy authPolicy = new AuthorizationPolicy();
authPolicy.setUserName("Hello");
authPolicy.setPassword("world");
+ authPolicy.setAuthorizationType("Basic");
message = getNewMessage();
message.put(AuthorizationPolicy.class, authPolicy);
Modified:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/http/HTTPConduitTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/http/HTTPConduitTest.java?rev=737237&r1=737236&r2=737237&view=diff
==============================================================================
---
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/http/HTTPConduitTest.java
(original)
+++
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/http/HTTPConduitTest.java
Fri Jan 23 23:06:21 2009
@@ -42,6 +42,7 @@
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.BusApplicationContext;
import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.configuration.security.FiltersType;
@@ -51,7 +52,7 @@
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
import org.apache.cxf.transport.http.HTTPConduit;
-import org.apache.cxf.transport.http.HttpBasicAuthSupplier;
+import org.apache.cxf.transport.http.HttpAuthSupplier;
import org.apache.cxf.transport.http.MessageTrustDecider;
import org.apache.cxf.transport.http.URLConnectionInfo;
import org.apache.cxf.transport.http.UntrustedURLConnectionIOException;
@@ -722,7 +723,7 @@
}
- public class MyBasicAuthSupplier extends HttpBasicAuthSupplier {
+ public class MyBasicAuthSupplier extends HttpAuthSupplier {
String realm;
String user;
@@ -740,8 +741,8 @@
pass = p;
}
@Override
- public UserPass getPreemptiveUserPass(
- String conduitName,
+ public String getPreemptiveAuthorization(
+ HTTPConduit conduit,
URL currentURL,
Message message
) {
@@ -753,11 +754,12 @@
* through the realms.
*/
@Override
- public UserPass getUserPassForRealm(
- String conduitName,
+ public String getAuthorizationForRealm(
+ HTTPConduit conduit,
URL currentURL,
Message message,
- String reqestedRealm
+ String reqestedRealm,
+ String fullHeader
) {
if (realm != null && realm.equals(reqestedRealm)) {
return createUserPass(user, pass);
@@ -777,6 +779,12 @@
return null;
}
+ private String createUserPass(String usr, String pwd) {
+ String userpass = usr + ":" + pwd;
+ String token = Base64Utility.encode(userpass.getBytes());
+ return "Basic " + token;
+ }
+
}
/**
@@ -818,7 +826,7 @@
// 401 for realm Cronus. If we supply any name other
// than Edward, George, or Mary, with the pass of "password"
// we should succeed.
- http.setBasicAuthSupplier(
+ http.setAuthSupplier(
new MyBasicAuthSupplier("Cronus", "Betty", "password"));
// We actually get our answer from Bethal at the end of the
@@ -827,9 +835,9 @@
assertTrue("Unexpected answer: " + answer,
"Bonjour from Bethal".equals(answer));
- // Uhe loop auth supplier,
+ // The loop auth supplier,
// We should die with looping realms.
- http.setBasicAuthSupplier(new MyBasicAuthSupplier());
+ http.setAuthSupplier(new MyBasicAuthSupplier());
try {
answer = gordy.sayHi();