cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cschnei...@apache.org
Subject svn commit: r1052233 - in /cxf/trunk: rt/transports/http/src/main/java/org/apache/cxf/transport/http/ rt/transports/http/src/test/java/org/apache/cxf/transport/http/ systests/transports/src/test/java/digestauth/ systests/transports/src/test/java/digest...
Date Thu, 23 Dec 2010 11:59:57 GMT
Author: cschneider
Date: Thu Dec 23 11:59:56 2010
New Revision: 1052233

URL: http://svn.apache.org/viewvc?rev=1052233&view=rev
Log:
CXF-3216 Refactor http authentication to make it more flexible and simpler. Add spnego kerberos
auth support

Added:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DefaultBasicAuthSupplier.java
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/SpnegoAuthSupplier.java
    cxf/trunk/systests/transports/src/test/java/digestauth/
    cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/
    cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/beans.xml
    cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/web.xml
    cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/
    cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthTest.java
    cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestServer.java
    cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/GreeterImpl.java
    cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/jetty-realm.properties
Modified:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
    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/HttpAuthHeader.java
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpBasicAuthSupplier.java
    cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/DigestAuthSupplierTest.java
    cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitTest.java

Added: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DefaultBasicAuthSupplier.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DefaultBasicAuthSupplier.java?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DefaultBasicAuthSupplier.java
(added)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DefaultBasicAuthSupplier.java
Thu Dec 23 11:59:56 2010
@@ -0,0 +1,49 @@
+/**
+ * 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.net.URL;
+
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.message.Message;
+
+final class DefaultBasicAuthSupplier extends HttpAuthSupplier {
+    DefaultBasicAuthSupplier() {
+        super();
+    }
+
+    @Override
+    public String getPreemptiveAuthorization(HTTPConduit conduit, URL currentURL, Message
message) {
+        AuthorizationPolicy effectiveAuthPolicy = conduit.getEffectiveAuthPolicy(message);
+        if (effectiveAuthPolicy.getUserName() != null && effectiveAuthPolicy.getPassword()
!= null) {
+            return HttpBasicAuthSupplier.getBasicAuthHeader(effectiveAuthPolicy.getUserName(),

+                                                            effectiveAuthPolicy.getPassword());
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public String getAuthorizationForRealm(HTTPConduit conduit, URL currentURL, Message message,
+                                           String realm, String fullHeader) {
+        return getPreemptiveAuthorization(conduit, currentURL, message);
+    }
+
+
+}
\ No newline at end of file

Modified: 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=1052233&r1=1052232&r2=1052233&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
(original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/DigestAuthSupplier.java
Thu Dec 23 11:59:56 2010
@@ -64,8 +64,9 @@ public class DigestAuthSupplier extends 
     public String getAuthorizationForRealm(HTTPConduit conduit, URL currentURL,
                                            Message message,
                                            String realm, String fullHeader) {
+        AuthorizationPolicy authPolicy = conduit.getEffectiveAuthPolicy(message);
         HttpAuthHeader authHeader = new HttpAuthHeader(fullHeader);
-        if (authHeader.authTypeIsDigest()) {
+        if (authHeader.authTypeIsDigest() && authPolicy != null) {
             Map<String, String> map = authHeader.getParams();
             if ("auth".equals(map.get("qop"))
                 || !map.containsKey("qop")) {
@@ -85,9 +86,10 @@ public class DigestAuthSupplier extends 
                     di.method = "POST";
                 }
                 authInfo.put(currentURL, di);
+                
                 return di.generateAuth(currentURL.getFile(), 
-                                       getUsername(conduit, message),
-                                       getPassword(conduit, message));
+                                       authPolicy.getUserName(),
+                                       authPolicy.getPassword());
             }
             
         }
@@ -96,34 +98,11 @@ public class DigestAuthSupplier extends 
     @Override
     public String getPreemptiveAuthorization(HTTPConduit conduit, URL currentURL, Message
message) {
         DigestInfo di = authInfo.get(currentURL);
+        AuthorizationPolicy authPolicy = conduit.getEffectiveAuthPolicy(message);
         if (di != null) {
             return di.generateAuth(currentURL.getFile(), 
-                                   getUsername(conduit, message),
-                                   getPassword(conduit, message));            
-        }
-        return null;
-    }
-
-    private String getPassword(HTTPConduit conduit, Message message) {
-        AuthorizationPolicy policy = getPolicy(conduit, message);
-        return policy != null ? policy.getPassword() : null;
-    }
-
-    private String getUsername(HTTPConduit conduit, Message message) {
-        AuthorizationPolicy policy = getPolicy(conduit, message);
-        return policy != null ? policy.getUserName() : null;
-    }
-
-    private AuthorizationPolicy getPolicy(HTTPConduit conduit, Message message) {
-        AuthorizationPolicy policy 
-            = (AuthorizationPolicy)message.getContextualProperty(AuthorizationPolicy.class.getName());
-        if (policy == null) {
-            policy = conduit.getAuthorization();
-        }
-        if (policy != null
-            && (!policy.isSetAuthorizationType()
-                || "Digest".equals(policy.getAuthorizationType()))) {
-            return policy;
+                                   authPolicy.getUserName(),
+                                   authPolicy.getPassword());            
         }
         return null;
     }

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=1052233&r1=1052232&r2=1052233&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
Thu Dec 23 11:59:56 2010
@@ -469,19 +469,18 @@ public class HTTPConduit 
                 
         boolean isChunking = false;
         int chunkThreshold = 0;
-        // We must cache the request if we have basic auth supplier
-        // without preemptive basic auth.
-        if (authSupplier != null) {
-            String auth = authSupplier.getPreemptiveAuthorization(
-                    this, currentURL, message);
-            if (auth == null || authSupplier.requiresRequestCaching()) {
-                needToCacheRequest = true;
-                isChunking = false;
-                LOG.log(Level.FINE,
-                        "Auth Supplier, but no Premeptive User Pass or Digest auth (nonce
may be stale)"
-                        + " We must cache request.");
-            }
-            message.put("AUTH_VALUE", auth);
+        final AuthorizationPolicy effectiveAuthPolicy = getEffectiveAuthPolicy(message);
+        if (this.authSupplier == null) {
+            String authType = effectiveAuthPolicy.getAuthorizationType();
+            this.authSupplier = createAuthSupplier(authType);
+        }
+
+        if (this.authSupplier.requiresRequestCaching()) {
+            needToCacheRequest = true;
+            isChunking = false;
+            LOG.log(Level.FINE,
+                    "Auth Supplier, but no Premeptive User Pass or Digest auth (nonce may
be stale)"
+                    + " We must cache request.");
         }
         if (csPolicy.isAutoRedirect()) {
             needToCacheRequest = true;
@@ -534,6 +533,16 @@ public class HTTPConduit 
         // We are now "ready" to "send" the message. 
     }
 
+    private HttpAuthSupplier createAuthSupplier(String authType) {
+        if (HttpAuthHeader.AUTH_TYPE_NEGOTIATE.equals(authType)) {
+            return new SpnegoAuthSupplier();
+        } else if (HttpAuthHeader.AUTH_TYPE_DIGEST.equals(authType)) {
+            return new DigestAuthSupplier();
+        } else {
+            return new DefaultBasicAuthSupplier();
+        }
+    }
+
     private static int determineReceiveTimeout(Message message,
             HTTPClientPolicy csPolicy) {
         long rtimeout = csPolicy.getReceiveTimeout();
@@ -718,53 +727,17 @@ public class HTTPConduit 
             URL url
     ) {
         Headers headers = new Headers(message);
-        AuthorizationPolicy authPolicy = getAuthorization();
-        AuthorizationPolicy newPolicy = message.get(AuthorizationPolicy.class);
-        
-        String authString = null;
-        if (authSupplier != null 
-            && (newPolicy == null
-                || (!"Basic".equals(newPolicy.getAuthorizationType())
-                    && newPolicy.getAuthorization() == null))) {
-            authString = (String)message.get("AUTH_VALUE");
-            if (authString == null) {
-                authString = authSupplier.getPreemptiveAuthorization(
-                    this, url, message);
-            } else {
-                message.remove("AUTH_VALUE");
-            }
-            if (authString != null) {
-                headers.setAuthorization(authString);
-            }
-            return;
-        }
-        String userName = null;
-        String passwd = null;
-        if (null != newPolicy) {
-            userName = newPolicy.getUserName();
-            passwd = newPolicy.getPassword();
-        }
-
-        if (userName == null 
-            && authPolicy != null && authPolicy.isSetUserName()) {
-            userName = authPolicy.getUserName();
-        }
-        if (userName != null) {
-            if (passwd == null 
-                && authPolicy != null && authPolicy.isSetPassword()) {
-                passwd = authPolicy.getPassword();
-            }
-            headers.setAuthorization(HttpBasicAuthSupplier.getBasicAuthHeader(userName, passwd));
-        } else if (authPolicy != null 
-                && authPolicy.isSetAuthorizationType() 
-                && authPolicy.isSetAuthorization()) {
-            headers.setAuthorization(authPolicy.getAuthorizationType() + " " + authPolicy.getAuthorization());
+        String authString = authSupplier.getPreemptiveAuthorization(this, url, message);
+        if (authString != null) {
+            headers.setAuthorization(authString);
         }
+        
+        // TODO Also use an authSupplier for proxy auth
         AuthorizationPolicy proxyAuthPolicy = getProxyAuthorization();
         if (proxyAuthPolicy != null && proxyAuthPolicy.isSetUserName()) {
-            userName = proxyAuthPolicy.getUserName();
+            String userName = proxyAuthPolicy.getUserName();
             if (userName != null) {
-                passwd = "";
+                String passwd = "";
                 if (proxyAuthPolicy.isSetPassword()) {
                     passwd = proxyAuthPolicy.getPassword();
                 }
@@ -788,6 +761,26 @@ public class HTTPConduit 
         }
         return null;
     }
+    
+    /**
+     * Determines effective auth policy from message, conduit and empty default
+     * with priority from first to last
+     * 
+     * @param message
+     * @return effective AthorizationPolicy
+     */
+    public AuthorizationPolicy getEffectiveAuthPolicy(Message message) {
+        AuthorizationPolicy authPolicy = getAuthorization();
+        AuthorizationPolicy newPolicy = message.get(AuthorizationPolicy.class);
+        AuthorizationPolicy effectivePolicy = newPolicy;
+        if (effectivePolicy == null) {
+            effectivePolicy = authPolicy;
+        }
+        if (effectivePolicy == null) {
+            effectivePolicy = new AuthorizationPolicy();
+        }
+        return effectivePolicy;
+    }
 
     /**
      * This method gets the Authorization Policy that was configured or 

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthHeader.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthHeader.java?rev=1052233&r1=1052232&r2=1052233&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthHeader.java
(original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpAuthHeader.java
Thu Dec 23 11:59:56 2010
@@ -35,13 +35,14 @@ public final class HttpAuthHeader {
     private Map<String, String> params;
 
     public HttpAuthHeader(String fullHeader) {
-        this.fullHeader = fullHeader;
-        int spacePos = fullHeader.indexOf(' ');
+        this.fullHeader = (fullHeader == null) ? "" : fullHeader;
+        int spacePos = this.fullHeader.indexOf(' ');
         if (spacePos == -1) {
-            this.authType = fullHeader;
+            this.authType = this.fullHeader;
+            this.fullContent = "";
         } else {
-            this.authType = fullHeader.substring(0, spacePos);
-            this.fullContent = fullHeader.substring(spacePos + 1);
+            this.authType = this.fullHeader.substring(0, spacePos);
+            this.fullContent = this.fullHeader.substring(spacePos + 1);
         }
         this.params = parseHeader();
     }

Modified: 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/HttpBasicAuthSupplier.java?rev=1052233&r1=1052232&r2=1052233&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/HttpBasicAuthSupplier.java
Thu Dec 23 11:59:56 2010
@@ -52,6 +52,7 @@ public abstract class HttpBasicAuthSuppl
      *
      */
     protected HttpBasicAuthSupplier() {
+        super();
     }
     
     /**

Added: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/SpnegoAuthSupplier.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/SpnegoAuthSupplier.java?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/SpnegoAuthSupplier.java
(added)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/SpnegoAuthSupplier.java
Thu Dec 23 11:59:56 2010
@@ -0,0 +1,172 @@
+/**
+ * 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.net.URL;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.message.Message;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+public class SpnegoAuthSupplier extends HttpAuthSupplier {
+    private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
+    //private static final String SPNEGO_OID = "1.3.6.1.5.5.2";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(HTTPConduit.class);
+
+    private LoginContext lc;
+
+    @Override
+    public String getPreemptiveAuthorization(HTTPConduit conduit, URL currentURL, Message
message) {
+        AuthorizationPolicy authPolicy = conduit.getEffectiveAuthPolicy(message);
+        if (!HttpAuthHeader.AUTH_TYPE_NEGOTIATE.equals(authPolicy.getAuthorizationType()))
{
+            return null;
+        }
+        try {
+            String spn = "HTTP/" + currentURL.getHost();
+            LOG.fine("Adding authorization service ticket for service principal name: " +
spn);
+            byte[] token = getToken(authPolicy, spn);
+            return HttpAuthHeader.AUTH_TYPE_NEGOTIATE + " " + Base64Utility.encode(token);
+        } catch (LoginException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        } catch (GSSException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public String getAuthorizationForRealm(HTTPConduit conduit, URL currentURL, Message message,
+                                           String realm, String fullHeader) {
+        return getPreemptiveAuthorization(conduit, currentURL, message);
+    }
+
+    /**
+     * Create and return service ticket token
+     * 
+     * @param authPolicy
+     * @param context
+     * @return
+     * @throws GSSException
+     * @throws LoginException
+     */
+    private byte[] getToken(AuthorizationPolicy authPolicy, final GSSContext context) throws
GSSException,
+            LoginException {
+        final byte[] token = new byte[0];
+
+        if (authPolicy.getUserName() == null || authPolicy.getUserName().trim().length()
== 0) {
+            return context.initSecContext(token, 0, token.length);
+        }
+
+        if (lc == null) {
+            lc = new LoginContext(authPolicy.getAuthorization(), getUsernamePasswordHandler(
+                authPolicy.getUserName(), authPolicy.getPassword()));
+            lc.login();
+        }
+
+        try {
+            return (byte[]) Subject.doAs(lc.getSubject(), new CreateServiceTicketAction(context,
token));
+        } catch (PrivilegedActionException e) {
+            if (e.getCause() instanceof GSSException) {
+                throw (GSSException) e.getCause();
+            }
+            LOG.log(Level.SEVERE, "initSecContext", e);
+            return null;
+        }
+    }
+
+    /**
+     * Create and return a service ticket token for a given service principal
+     * name
+     * 
+     * @param proxyAuthPolicy
+     * @param spn
+     * @return service ticket token
+     * @throws GSSException
+     * @throws LoginException
+     */
+    private byte[] getToken(AuthorizationPolicy proxyAuthPolicy, String spn) throws GSSException,

+        LoginException {
+        GSSManager manager = GSSManager.getInstance();
+        GSSName serverName = manager.createName(spn, null);
+
+        // TODO Is it correct to use kerberos oid instead of spnego here?
+        Oid oid = new Oid(KERBEROS_OID);
+        
+        GSSContext context = manager
+                .createContext(serverName.canonicalize(oid), oid, null, GSSContext.DEFAULT_LIFETIME);
+        // TODO Do we need mutual auth. Will the code we have really work with
+        // mutual auth?
+        context.requestMutualAuth(true);
+        // TODO Credential delegation could be a security hole if it was not
+        // intended. Both settings should be configurable
+        context.requestCredDeleg(true);
+
+        return getToken(proxyAuthPolicy, context);
+    }
+
+    private final class CreateServiceTicketAction implements PrivilegedExceptionAction<byte[]>
{
+        private final GSSContext context;
+        private final byte[] token;
+
+        private CreateServiceTicketAction(GSSContext context, byte[] token) {
+            this.context = context;
+            this.token = token;
+        }
+
+        public byte[] run() throws GSSException {
+            return context.initSecContext(token, 0, token.length);
+        }
+    }
+    
+    public static CallbackHandler getUsernamePasswordHandler(final String username, final
String password) {
+        final CallbackHandler handler = new CallbackHandler() {
+
+            public void handle(final Callback[] callback) {
+                for (int i = 0; i < callback.length; i++) {
+                    if (callback[i] instanceof NameCallback) {
+                        final NameCallback nameCallback = (NameCallback) callback[i];
+                        nameCallback.setName(username);
+                    } else if (callback[i] instanceof PasswordCallback) {
+                        final PasswordCallback passCallback = (PasswordCallback) callback[i];
+                        passCallback.setPassword(password.toCharArray());
+                    }
+                }
+            }
+        };
+        return handler;
+    }
+}

Modified: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/DigestAuthSupplierTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/DigestAuthSupplierTest.java?rev=1052233&r1=1052232&r2=1052233&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/DigestAuthSupplierTest.java
(original)
+++ cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/DigestAuthSupplierTest.java
Thu Dec 23 11:59:56 2010
@@ -76,7 +76,8 @@ public class DigestAuthSupplierTest {
         authorizationPolicy.setUserName("testUser");
         authorizationPolicy.setPassword("testPassword");
         
-        EasyMock.expect(conduit.getAuthorization()).andReturn(authorizationPolicy).atLeastOnce();
+        EasyMock.expect(conduit.getEffectiveAuthPolicy(EasyMock.isA(Message.class)))
+            .andReturn(authorizationPolicy).atLeastOnce();
         URL url = new URL("http://myserver");
         Message message = new MessageImpl();
         control.replay();

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=1052233&r1=1052232&r2=1052233&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
Thu Dec 23 11:59:56 2010
@@ -213,7 +213,9 @@ public class HTTPConduitTest extends Ass
                 "Basic " + Base64Utility.encode("Gandalf:staff".getBytes()),
                 headers.get("Authorization").get(0));
 
-        // Setting authorization policy on the message should override all.
+        conduit.setAuthSupplier(null);
+        // Setting authorization policy on the message should override 
+        // conduit setting
         AuthorizationPolicy authPolicy = new AuthorizationPolicy();
         authPolicy.setUserName("Hello");
         authPolicy.setPassword("world");

Added: cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/beans.xml?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/beans.xml (added)
+++ cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/beans.xml Thu Dec 23 11:59:56
2010
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns:http="http://cxf.apache.org/transports/http/configuration"
+  xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
+  xmlns:jaxws="http://cxf.apache.org/jaxws"
+  xsi:schemaLocation="
+  		   http://cxf.apache.org/configuration/security
+  		      http://cxf.apache.org/schemas/configuration/security.xsd
+           http://cxf.apache.org/transports/http/configuration
+              http://cxf.apache.org/schemas/configuration/http-conf.xsd
+           http://cxf.apache.org/transports/http-jetty/configuration
+              http://cxf.apache.org/schemas/configuration/http-jetty.xsd
+           http://www.springframework.org/schema/beans
+              http://www.springframework.org/schema/beans/spring-beans.xsd
+           http://cxf.apache.org/jaxws
+              http://cxf.apache.org/schemas/jaxws.xsd">
+              
+  <import resource="classpath:META-INF/cxf/cxf.xml"/>
+  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
+  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
+
+  <http:destination name="{http://apache.org/hello_world}Mortimer.http-destination">
+    <!-- Nothing to Configure here for Mortimer -->
+  </http:destination>
+  
+  <bean id="greeterImpl" class="org.apache.cxf.systest.http.auth.GreeterImpl">
+  </bean>
+  
+  <jaxws:endpoint address="/greeter" implementor="#greeterImpl" publish="true"/>
+</beans>

Added: cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/web.xml?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/web.xml (added)
+++ cxf/trunk/systests/transports/src/test/java/digestauth/WEB-INF/web.xml Thu Dec 23 11:59:56
2010
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+<!-- 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. -->
+
+<web-app>
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>WEB-INF/beans.xml</param-value>
+	</context-param>
+
+	<listener>
+		<listener-class>
+			org.springframework.web.context.ContextLoaderListener
+		</listener-class>
+	</listener>
+
+	<servlet>
+		<servlet-name>CXFServlet</servlet-name>
+		<display-name>CXF Servlet</display-name>
+		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>CXFServlet</servlet-name>
+		<url-pattern>/*</url-pattern>
+
+	</servlet-mapping>
+
+	<security-constraint>
+
+		<web-resource-collection>
+			<web-resource-name>CXFServlet</web-resource-name>
+			<url-pattern>/*</url-pattern>
+		</web-resource-collection>
+
+		<auth-constraint>
+			<role-name>ROLE_USER</role-name>
+		</auth-constraint>
+	</security-constraint>
+
+	<login-config>
+		<auth-method>DIGEST</auth-method>
+		<realm-name>BookStoreRealm</realm-name>
+	</login-config>
+
+	<security-role>
+		<role-name>ROLE_USER</role-name>
+	</security-role>
+
+</web-app>

Added: cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthTest.java?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthTest.java
(added)
+++ cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthTest.java
Thu Dec 23 11:59:56 2010
@@ -0,0 +1,111 @@
+/**
+ * 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.systest.http.auth;
+
+
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class DigestAuthTest extends AbstractBusClientServerTestBase {
+
+    private final QName serviceName = 
+        new QName("http://apache.org/hello_world", "SOAPService");
+    private final QName mortimerQ = 
+        new QName("http://apache.org/hello_world", "Mortimer");
+    public DigestAuthTest() {
+    }
+    
+    @BeforeClass
+    public static void startServer() {
+        launchServer(DigestServer.class);
+    }
+
+    @Test    
+    public void testDigestAuth() throws Exception {
+        URL wsdl = getClass().getResource("../resources/greeting.wsdl");
+        assertNotNull("WSDL is null", wsdl);
+
+        SOAPService service = new SOAPService(wsdl, serviceName);
+        assertNotNull("Service is null", service);
+
+        Greeter mortimer = service.getPort(mortimerQ, Greeter.class);
+        assertNotNull("Port is null", mortimer);
+        
+        setAddress(mortimer, "http://localhost:9000/digestauth/greeter");
+        
+        Client client = ClientProxy.getClient(mortimer);
+        
+        HTTPConduit http = 
+            (HTTPConduit) client.getConduit();
+        AuthorizationPolicy authPolicy = new AuthorizationPolicy();
+        authPolicy.setAuthorizationType("Digest");
+        authPolicy.setUserName("foo");
+        authPolicy.setPassword("bar");
+        http.setAuthorization(authPolicy);
+
+        String answer = mortimer.sayHi();
+        assertEquals("Unexpected answer: " + answer, 
+                "Hi", answer);
+
+    }
+    
+    @Test    
+    public void testNoAuth() throws Exception {
+        URL wsdl = getClass().getResource("../resources/greeting.wsdl");
+        assertNotNull("WSDL is null", wsdl);
+
+        SOAPService service = new SOAPService(wsdl, serviceName);
+        assertNotNull("Service is null", service);
+
+        Greeter mortimer = service.getPort(mortimerQ, Greeter.class);
+        assertNotNull("Port is null", mortimer);
+        
+        setAddress(mortimer, "http://localhost:9000/digestauth/greeter");
+
+        try {
+            String answer = mortimer.sayHi();
+            Assert.fail("Unexpected reply (" + answer + "). Should throw exception");
+        } catch (SOAPFaultException e) {
+            // TODO do we really expect Can't find input stream here. I rather would expect
+            // authorization failed with some infos
+            Throwable cause = e.getCause();
+            Assert.assertEquals(RuntimeException.class, cause.getClass());
+            RuntimeException rte = (RuntimeException)cause;
+            Assert.assertTrue(rte.getMessage().startsWith("Can't find input stream"));
+        }
+    }
+
+}
+

Added: cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestServer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestServer.java?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestServer.java
(added)
+++ cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestServer.java
Thu Dec 23 11:59:56 2010
@@ -0,0 +1,97 @@
+/**
+ * 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.systest.http.auth;
+
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+public class DigestServer extends AbstractBusTestServerBase {
+    public static final String PORT = allocatePort(DigestServer.class);
+
+    private org.eclipse.jetty.server.Server server;
+
+    public DigestServer() {
+    }
+
+    protected void configureServer() throws Exception {
+        URL resource = getClass()
+            .getResource("jetty-realm.properties");
+        LoginService realm = 
+            new HashLoginService("BookStoreRealm", resource.toString());
+        server.addBean(realm);
+    }
+    
+    protected void run() {
+        System.out.println("Starting Server");
+
+        server = new org.eclipse.jetty.server.Server();
+
+        SelectChannelConnector connector = new SelectChannelConnector();
+        connector.setPort(Integer.parseInt(PORT));
+        server.setConnectors(new Connector[] {connector});
+
+        WebAppContext webappcontext = new WebAppContext();
+        webappcontext.setContextPath("/digestauth");
+
+        String warPath = null;
+        try {
+            URL res = getClass().getResource("/digestauth");
+            warPath = res.toURI().getPath();
+        } catch (URISyntaxException e1) {
+            e1.printStackTrace();
+        }
+        
+        webappcontext.setWar(warPath);
+
+        HandlerCollection handlers = new HandlerCollection();
+        handlers.setHandlers(new Handler[] {webappcontext, new DefaultHandler()});
+
+        server.setHandler(handlers);
+        
+        try {
+            configureServer();
+            server.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }     
+    }
+    
+    public static void main(String args[]) {
+        try {
+            DigestServer s = new DigestServer();
+            s.start();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            System.exit(-1);
+        } finally {
+            System.out.println("done!");
+        }
+    }
+
+}

Added: cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/GreeterImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/GreeterImpl.java?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/GreeterImpl.java
(added)
+++ cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/GreeterImpl.java
Thu Dec 23 11:59:56 2010
@@ -0,0 +1,40 @@
+/**
+ * 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.systest.http.auth;
+
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.messages.PingMeFault;
+
+public class GreeterImpl implements Greeter {
+
+    public String sayHi() {
+        return "Hi";
+    }
+
+    public void pingMe() throws PingMeFault {
+        // TODO Auto-generated method stub
+
+    }
+
+    public String greetMe(String requestType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Added: cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/jetty-realm.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/jetty-realm.properties?rev=1052233&view=auto
==============================================================================
--- cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/jetty-realm.properties
(added)
+++ cxf/trunk/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/jetty-realm.properties
Thu Dec 23 11:59:56 2010
@@ -0,0 +1,2 @@
+foo: bar,ROLE_USER
+



Mime
View raw message