You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2010/10/14 18:22:14 UTC

svn commit: r1022599 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/common/security/ rt/core/src/main/java/org/apache/cxf/interceptor/security/ rt/core/src/test/java/org/apache/cxf/interceptor/security/ rt/ws/security/src/main/java/org/apa...

Author: sergeyb
Date: Thu Oct 14 16:22:13 2010
New Revision: 1022599

URL: http://svn.apache.org/viewvc?rev=1022599&view=rev
Log:
[CXF-3063] : Initial code for using WSSE tokens for authorization decisions without extending WSS4JInInterceptor

Added:
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java   (with props)
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java   (with props)
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java   (with props)
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java   (with props)
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java   (with props)
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java   (with props)
    cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java   (with props)
Removed:
    cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
Modified:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
    cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java
    cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java
    cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml
    cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,23 @@
+/**
+ * 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.common.security;
+
+public interface SecurityToken {
+    TokenType getTokenType();
+}

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,23 @@
+/**
+ * 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.common.security;
+
+public enum TokenType {
+    UsernameToken
+}

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,71 @@
+/**
+ * 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.common.security;
+
+public class UsernameToken implements SecurityToken {
+
+    private String name;
+    private String password;
+    private String passwordType;
+    private boolean isHashed;
+    private String nonce;
+    private String createdTime;
+    
+    public UsernameToken(String name,
+                         String password,
+                         String passwordType,
+                         boolean isHashed,
+                         String nonce,
+                         String createdTime) {
+        this.name = name;
+        this.password = password;
+        this.passwordType = passwordType;
+        this.isHashed = isHashed;
+        this.nonce = nonce;
+        this.createdTime = createdTime;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String getPasswordType() {
+        return passwordType;
+    }
+
+    public boolean isHashed() {
+        return isHashed;
+    }
+
+    public String getNonce() {
+        return nonce;
+    }
+
+    public String getCreatedTime() {
+        return createdTime;
+    }
+    
+    public TokenType getTokenType() {
+        return TokenType.UsernameToken;
+    }
+}

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,79 @@
+/**
+ * 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.interceptor.security;
+
+import java.security.Principal;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.SecurityToken;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.security.SecurityContext;
+
+public abstract class AbstractSecurityContextInInterceptor extends AbstractPhaseInterceptor<Message> {
+
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(AbstractSecurityContextInInterceptor.class);
+    
+    public AbstractSecurityContextInInterceptor() {
+        super(Phase.PRE_INVOKE);
+    }
+    
+    public void handleMessage(Message message) throws Fault {
+        SecurityToken token = message.get(SecurityToken.class);
+        if (token == null) {
+            reportSecurityException("Security Token is not available on the current message");
+        }
+        
+        SecurityContext context = message.get(SecurityContext.class);
+        if (context == null || context.getUserPrincipal() == null) {
+            reportSecurityException("User Principal is not available on the current message");
+        }
+        
+        Subject subject = null;
+        try {
+            subject = createSubject(token);
+        } catch (Exception ex) {
+            reportSecurityException("Failed Authentication : Subject has not been created, " 
+                                    + ex.getMessage()); 
+        }
+        if (subject == null || subject.getPrincipals().size() == 0) {
+            reportSecurityException("Failed Authentication : Invalid Subject");
+        }
+        
+        SecurityContext sc = createSecurityContext(context.getUserPrincipal(), subject);
+        message.put(SecurityContext.class, sc);
+    }
+    
+    protected SecurityContext createSecurityContext(Principal p, Subject subject) {
+        return new DefaultSecurityContext(p, subject);
+    }
+    
+    protected abstract Subject createSubject(SecurityToken token);
+    
+    protected void reportSecurityException(String errorMessage) {
+        LOG.severe(errorMessage);
+        throw new SecurityException(errorMessage);
+    }
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java Thu Oct 14 16:22:13 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.interceptor.security;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SecurityToken;
+import org.apache.cxf.common.security.TokenType;
+import org.apache.cxf.common.security.UsernameToken;
+
+public abstract class AbstractUsernameTokenInInterceptor extends AbstractSecurityContextInInterceptor {
+    
+    protected Subject createSubject(SecurityToken token) {
+        if (token.getTokenType() != TokenType.UsernameToken) {
+            reportSecurityException("Unsupported token type " + token.getTokenType().toString());
+        }
+        UsernameToken ut = (UsernameToken)token;
+        return createSubject(ut);
+    }
+    
+    protected abstract Subject createSubject(UsernameToken token);
+    
+    
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.interceptor.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.security.SecurityContext;
+
+/**
+ * SecurityContext which implements isUserInRole using the
+ * following approach : skip the first Subject principal, and then checks
+ * Groups the principal is a member of
+ * 
+ * TODO : consider moving this class into common/security
+ */
+public class DefaultSecurityContext implements SecurityContext {
+
+    private Principal p;
+    private Subject subject; 
+    
+    public DefaultSecurityContext(Principal p, Subject subject) {
+        this.p = p;
+        this.subject = subject;
+    }
+    
+    public Principal getUserPrincipal() {
+        return p;
+    }
+    public boolean isUserInRole(String role) {
+        if (subject == null || subject.getPrincipals().size() <= 1) {
+            return false;
+        }
+        for (Principal principal : subject.getPrincipals()) {
+            if (principal instanceof Group && checkGroup((Group)principal, role)) { 
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected boolean checkGroup(Group group, String role) {
+        if (group.getName().equals(role)) {
+            return true;
+        }
+            
+        for (Enumeration<? extends Principal> members = group.members(); members.hasMoreElements();) {
+            // this might be a plain role but could represent a group consisting of other groups/roles
+            Principal member = members.nextElement();
+            if (member.getName().equals(role) 
+                || member instanceof Group && checkGroup((Group)member, role)) {
+                return true;
+            }
+        }
+        return false;    
+    }
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java (added)
+++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,75 @@
+/**
+ * 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.interceptor.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.common.security.SimplePrincipal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DefaultSecurityContextTest extends Assert {
+
+    @Test
+    public void testUserNotInRole() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        assertFalse(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+    @Test
+    public void testUserInRole() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        s.getPrincipals().add(new SimpleGroup("friend", p));
+        assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+    @Test
+    public void testUserInRole2() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        Group group = new SimpleGroup("Roles", p);
+        group.addMember(new SimpleGroup("friend"));
+        s.getPrincipals().add(group);
+        assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+    @Test
+    public void testUserInRole3() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        Group group = new SimpleGroup("Roles", p);
+        Group subgroup = new SimpleGroup("subgroup");
+        subgroup.addMember(new SimpleGroup("friend"));
+        group.addMember(subgroup);
+        s.getPrincipals().add(group);
+        assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+}

Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java Thu Oct 14 16:22:13 2010
@@ -31,6 +31,7 @@ public final class SecurityConstants {
     public static final String USERNAME = "ws-security.username";
     public static final String PASSWORD = "ws-security.password";
     public static final String VALIDATE_PASSWORD = "ws-security.validate.password";
+    public static final String USERNAME_TOKEN_NO_CALLBACKS = "ws-security.ut.no-callbacks";
     
     public static final String CALLBACK_HANDLER = "ws-security.callback-handler";
     

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java Thu Oct 14 16:22:13 2010
@@ -22,33 +22,24 @@ import java.io.IOException;
 import java.security.Principal;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Vector;
-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.UnsupportedCallbackException;
 import javax.xml.namespace.QName;
 
-import org.w3c.dom.Element;
-
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.interceptor.security.DefaultSecurityContext;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSDocInfo;
 import org.apache.ws.security.WSPasswordCallback;
-import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityEngine;
-import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.WSUsernameTokenPrincipal;
-import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.handler.RequestData;
-import org.apache.ws.security.message.token.UsernameToken;
 import org.apache.ws.security.processor.Processor;
 
 
@@ -69,8 +60,7 @@ import org.apache.ws.security.processor.
  * an application is expected to provide a password callback handler for decrypting the token only.     
  *
  */
-public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS4JInInterceptor 
-    implements Processor {
+public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS4JInInterceptor {
     
     private static final Logger LOG = 
         LogUtils.getL7dLogger(AbstractUsernameTokenAuthenticatingInterceptor.class);
@@ -130,11 +120,15 @@ public abstract class AbstractUsernameTo
         try {
             subject = createSubject(name, password, isDigest, nonce, created);
         } catch (Exception ex) {
-            throw new WSSecurityException("Failed Authentication : Subject has not been created", ex);
+            String errorMessage = "Failed Authentication : Subject has not been created";
+            LOG.severe(errorMessage);
+            throw new WSSecurityException(errorMessage, ex);
         }
         if (subject == null || subject.getPrincipals().size() == 0
             || !subject.getPrincipals().iterator().next().getName().equals(name)) {
-            throw new WSSecurityException("Failed Authentication : Invalid Subject");
+            String errorMessage = "Failed Authentication : Invalid Subject";
+            LOG.severe(errorMessage);
+            throw new WSSecurityException(errorMessage);
         }
         msg.put(Subject.class, subject);
     }
@@ -164,7 +158,7 @@ public abstract class AbstractUsernameTo
      * 
      */
     @Override
-    protected CallbackHandler getCallback(RequestData reqData, int doAction) 
+    protected CallbackHandler getCallback(RequestData reqData, int doAction, boolean utNoCallbacks) 
         throws WSSecurityException {
         
         // Given that a custom UT processor is used for dealing with digests 
@@ -174,63 +168,46 @@ public abstract class AbstractUsernameTo
         if ((doAction & WSConstants.UT) != 0) {
             CallbackHandler pwdCallback = null;
             try {
-                pwdCallback = super.getCallback(reqData, doAction);
+                pwdCallback = super.getCallback(reqData, doAction, false);
             } catch (Exception ex) {
                 // ignore
             }
-            return new DelegatingCallbackHandler(pwdCallback);
+            return new SubjectCreatingCallbackHandler(pwdCallback);
         }
         
-        return super.getCallback(reqData, doAction);
+        return super.getCallback(reqData, doAction, false);
     }
     
     @Override 
-    protected WSSecurityEngine getSecurityEngine() {
+    protected WSSecurityEngine getSecurityEngine(boolean utNoCallbacks) {
         if (!supportDigestPasswords) {
-            return super.getSecurityEngine();
+            return super.getSecurityEngine(false);
         }
         Map<QName, Object> profiles = new HashMap<QName, Object>(3);
-        profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), this);
-        profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), this);
+        
+        Processor processor = new CustomUsernameTokenProcessor();
+        profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+        profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), processor);
         return createSecurityEngine(profiles);
     }
     
-    public void handleToken(Element elem, 
-                            Crypto crypto, 
-                            Crypto decCrypto, 
-                            CallbackHandler cb, 
-                            WSDocInfo wsDocInfo, 
-                            Vector returnResults, 
-                            WSSConfig config) throws WSSecurityException {
-        new CustomUsernameTokenProcessor().handleToken(elem, crypto, decCrypto, cb, wsDocInfo, 
-                                                       returnResults, config);
-    }
-    
-    
-    protected class DelegatingCallbackHandler implements CallbackHandler {
+    protected class SubjectCreatingCallbackHandler extends DelegatingCallbackHandler {
 
-        private CallbackHandler pwdHandler;
-        
-        public DelegatingCallbackHandler(CallbackHandler pwdHandler) {
-            this.pwdHandler = pwdHandler;
+        public SubjectCreatingCallbackHandler(CallbackHandler pwdHandler) {
+            super(pwdHandler);
         }
         
-        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
-            for (Callback c : callbacks) {
-                if (c instanceof WSPasswordCallback) {
-                    WSPasswordCallback pc = (WSPasswordCallback)c;
-                    if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType()) 
-                        && pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
-                        AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
-                            pc.getIdentifier(), pc.getPassword(), false, null, null);
-                    } else if (pwdHandler != null) {
-                        pwdHandler.handle(callbacks);
-                    }
-                }
+        @Override
+        protected void handleCallback(Callback c) throws IOException {
+            if (c instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback)c;
+                if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType()) 
+                    && pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
+                    AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
+                        pc.getIdentifier(), pc.getPassword(), false, null, null);
+                } 
             }
-            
         }
-        
     }
     
     /**
@@ -239,56 +216,18 @@ public abstract class AbstractUsernameTo
      * override its handleUsernameToken only. 
      *
      */
-    private class CustomUsernameTokenProcessor implements Processor {
-        
-        private String utId;
-        private UsernameToken ut;
+    protected class CustomUsernameTokenProcessor extends UsernameTokenProcessorWithoutCallbacks {
         
-        @SuppressWarnings("unchecked")
-        public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, 
-            WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {
-            if (LOG.isLoggable(Level.FINE)) {
-                LOG.fine("Found UsernameToken list element");
-            }
-            
-            Principal principal = handleUsernameToken((Element) elem, cb);
-            returnResults.add(
-                0, 
-                new WSSecurityEngineResult(WSConstants.UT, principal, null, null, null)
-            );
-            utId = ut.getID();
-        }
-        
-        private WSUsernameTokenPrincipal handleUsernameToken(
-            Element token, CallbackHandler cb) throws WSSecurityException {
-            //
-            // Parse the UsernameToken element
-            //
-            ut = new UsernameToken(token, false);
-            String user = ut.getName();
-            String password = ut.getPassword();
-            String nonce = ut.getNonce();
-            String createdTime = ut.getCreated();
-            String pwType = ut.getPasswordType();
-            if (LOG.isLoggable(Level.FINE)) {
-                LOG.fine("UsernameToken user " + user);
-                LOG.fine("UsernameToken password " + password);
-            }
-            
+        @Override
+        protected WSUsernameTokenPrincipal createPrincipal(String user, 
+                                                           String password,
+                                                           boolean isHashed,
+                                                           String nonce,
+                                                           String createdTime,
+                                                           String pwType) throws WSSecurityException {
             AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
-                user, password, ut.isHashed(), nonce, createdTime);    
-            
-            WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, ut.isHashed());
-            principal.setNonce(nonce);
-            principal.setPassword(password);
-            principal.setCreatedTime(createdTime);
-            principal.setPasswordType(pwType);
-
-            return principal;
-        }
-
-        public String getId() {
-            return utId;
+                 user, password, isHashed, nonce, createdTime);
+            return super.createPrincipal(user, password, isHashed, nonce, createdTime, pwType);
         }
     }
     

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,48 @@
+/**
+ * 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.ws.security.wss4j;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class DelegatingCallbackHandler implements CallbackHandler {
+
+    private CallbackHandler pwdHandler;
+    
+    public DelegatingCallbackHandler(CallbackHandler pwdHandler) {
+        this.pwdHandler = pwdHandler;
+    }
+    
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+        for (Callback c : callbacks) {
+            handleCallback(c);
+        }
+        if (pwdHandler != null) {
+            pwdHandler.handle(callbacks);
+        }
+    }
+    
+    protected void handleCallback(Callback c) throws IOException {
+        // complete
+    }
+}

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -455,7 +455,7 @@ public class PolicyBasedWSS4JInIntercept
     }
     
     protected void doResults(SoapMessage msg, String actor, 
-                             SOAPMessage doc, Vector results) 
+                             SOAPMessage doc, Vector results, boolean utWithCallbacks) 
         throws SOAPException, XMLStreamException, WSSecurityException {
         
         AssertionInfoMap aim = msg.get(AssertionInfoMap.class);
@@ -502,12 +502,15 @@ public class PolicyBasedWSS4JInIntercept
                     for (AssertionInfo ai : ais) {
                         ai.setAsserted(true);
                     }
-                    WSUsernameTokenPrincipal princ 
-                        = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
-                    for (AssertionInfo ai : ais) {
-                        UsernameToken tok = (UsernameToken)ai.getAssertion();
-                        if (tok.isHashPassword() != princ.isPasswordDigest()) {
-                            ai.setNotAsserted("Password hashing policy not enforced");
+                    
+                    if (utWithCallbacks) {
+                        WSUsernameTokenPrincipal princ 
+                            = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+                        for (AssertionInfo ai : ais) {
+                            UsernameToken tok = (UsernameToken)ai.getAssertion();
+                            if (tok.isHashPassword() != princ.isPasswordDigest()) {
+                                ai.setNotAsserted("Password hashing policy not enforced");
+                            }
                         }
                     }
                 }
@@ -557,7 +560,7 @@ public class PolicyBasedWSS4JInIntercept
             assertPolicy(aim, SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
         }
         
-        super.doResults(msg, actor, doc, results);
+        super.doResults(msg, actor, doc, results, utWithCallbacks);
     }
     private void assertHeadersExists(AssertionInfoMap aim, SoapMessage msg, SOAPMessage doc) 
         throws SOAPException {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java Thu Oct 14 16:22:13 2010
@@ -45,6 +45,7 @@ import org.apache.cxf.headers.Header;
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.security.DefaultSecurityContext;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.Phase;
 import org.apache.cxf.security.SecurityContext;

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,107 @@
+/**
+ * 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.ws.security.wss4j;
+
+import java.security.Principal;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSUsernameTokenPrincipal;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.processor.Processor;
+
+
+/**
+ * UsernameToken processor which creates Principal 
+ * without delegating to CallbackHandlers
+ */
+public class UsernameTokenProcessorWithoutCallbacks implements Processor {
+    
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(UsernameTokenProcessorWithoutCallbacks.class);
+    
+    private String utId;
+    private UsernameToken ut;
+    
+    @SuppressWarnings("unchecked")
+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, 
+        WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Found UsernameToken list element");
+        }
+        
+        Principal principal = handleUsernameToken((Element) elem, cb);
+        returnResults.add(
+            0, 
+            new WSSecurityEngineResult(WSConstants.UT, principal, null, null, null)
+        );
+        utId = ut.getID();
+    }
+    
+    private WSUsernameTokenPrincipal handleUsernameToken(
+        Element token, CallbackHandler cb) throws WSSecurityException {
+        //
+        // Parse the UsernameToken element
+        //
+        ut = new UsernameToken(token, false);
+        String user = ut.getName();
+        String password = ut.getPassword();
+        String nonce = ut.getNonce();
+        String createdTime = ut.getCreated();
+        String pwType = ut.getPasswordType();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("UsernameToken user " + user);
+            LOG.fine("UsernameToken password " + password);
+        }
+        
+        return createPrincipal(user, password, ut.isHashed(), nonce, createdTime, pwType);
+    }
+
+    protected WSUsernameTokenPrincipal createPrincipal(String user, 
+                                                       String password,
+                                                       boolean isHashed,
+                                                       String nonce,
+                                                       String createdTime,
+                                                       String pwType) throws WSSecurityException {
+        WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, isHashed);
+        principal.setNonce(nonce);
+        principal.setPassword(password);
+        principal.setCreatedTime(createdTime);
+        principal.setPasswordType(pwType);
+
+        return principal;
+    }
+    
+    public String getId() {
+        return utId;
+    }
+}

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -21,6 +21,7 @@ package org.apache.cxf.ws.security.wss4j
 import java.io.IOException;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Vector;
@@ -46,9 +47,11 @@ import org.apache.cxf.binding.soap.saaj.
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.i18n.Message;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.UsernameToken;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.Phase;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.cxf.staxutils.StaxUtils;
@@ -149,13 +152,17 @@ public class WSS4JInInterceptor extends 
             return;
         }
         msg.put(SECURITY_PROCESSED, Boolean.TRUE);
+        
+        boolean utWithCallbacks = 
+            !MessageUtils.getContextualBoolean(msg, SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS, false);
+        
         WSSConfig config = (WSSConfig)msg.getContextualProperty(WSSConfig.class.getName()); 
         WSSecurityEngine engine;
         if (config != null) {
             engine = new WSSecurityEngine();
             engine.setWssConfig(config);
         } else {
-            engine = getSecurityEngine();
+            engine = getSecurityEngine(utWithCallbacks);
         }
         
         SOAPMessage doc = getSOAPMessage(msg);
@@ -192,7 +199,7 @@ public class WSS4JInInterceptor extends 
 
             String actor = (String)getOption(WSHandlerConstants.ACTOR);
 
-            CallbackHandler cbHandler = getCallback(reqData, doAction);
+            CallbackHandler cbHandler = getCallback(reqData, doAction, utWithCallbacks);
 
             /*
              * Get and check the Signature specific parameters first because
@@ -225,7 +232,7 @@ public class WSS4JInInterceptor extends 
                 checkSignatures(msg, reqData, wsResult);
                 checkTimestamps(msg, reqData, wsResult);
                 checkActions(msg, reqData, wsResult, actions);
-                doResults(msg, actor, doc, wsResult);
+                doResults(msg, actor, doc, wsResult, utWithCallbacks);
             } else { // no security header found
                 // Create an empty result vector to pass into the required validation
                 // methods.
@@ -360,8 +367,14 @@ public class WSS4JInInterceptor extends 
     protected void computeAction(SoapMessage msg, RequestData reqData) {
         
     }
+
     protected void doResults(SoapMessage msg, String actor, SOAPMessage doc, Vector wsResult)
         throws SOAPException, XMLStreamException, WSSecurityException {
+        doResults(msg, actor, doc, wsResult, false);
+    }
+
+    protected void doResults(SoapMessage msg, String actor, SOAPMessage doc, Vector wsResult, 
+        boolean utWithCallbacks) throws SOAPException, XMLStreamException, WSSecurityException {
         /*
          * All ok up to this point. Now construct and setup the security result
          * structure. The service may fetch this and check it.
@@ -405,7 +418,18 @@ public class WSS4JInInterceptor extends 
         for (WSSecurityEngineResult o : CastUtils.cast(wsResult, WSSecurityEngineResult.class)) {
             final Principal p = (Principal)o.get(WSSecurityEngineResult.TAG_PRINCIPAL);
             if (p != null) {
-                msg.put(PRINCIPAL_RESULT, p);                   
+                msg.put(PRINCIPAL_RESULT, p);
+                if (!utWithCallbacks && p instanceof WSUsernameTokenPrincipal) {
+                    WSUsernameTokenPrincipal utp = (WSUsernameTokenPrincipal)p;
+                    msg.put(org.apache.cxf.common.security.SecurityToken.class, 
+                            new UsernameToken(utp.getName(),
+                                              utp.getPassword(),
+                                              utp.getPasswordType(),
+                                              utp.isPasswordDigest(),
+                                              utp.getNonce(),
+                                              utp.getCreatedTime()));
+                    
+                }
                 SecurityContext sc = msg.get(SecurityContext.class);
                 if (sc == null || sc.getUserPrincipal() == null) {
                     msg.put(SecurityContext.class, createSecurityContext(p));
@@ -477,6 +501,21 @@ public class WSS4JInInterceptor extends 
         
     }
 
+    protected CallbackHandler getCallback(RequestData reqData, int doAction, boolean utWithCallbacks) 
+        throws WSSecurityException {
+        if (!utWithCallbacks && (doAction & WSConstants.UT) != 0) {
+            CallbackHandler pwdCallback = null;
+            try {
+                pwdCallback = getCallback(reqData, doAction);
+            } catch (Exception ex) {
+                // ignore
+            }
+            return new DelegatingCallbackHandler(pwdCallback);
+        } else {
+            return getCallback(reqData, doAction);
+        }
+    }
+    
     protected CallbackHandler getCallback(RequestData reqData, int doAction) throws WSSecurityException {
         /*
          * To check a UsernameToken or to decrypt an encrypted message we need a
@@ -535,11 +574,19 @@ public class WSS4JInInterceptor extends 
      * TODO the WSHandler base class defines secEngine to be static, which
      * is really bad, because the engine has mutable state on it.
      */
-    protected WSSecurityEngine
-    getSecurityEngine() {
+    protected WSSecurityEngine getSecurityEngine(boolean utWithCallbacks) {
         if (secEngineOverride != null) {
             return secEngineOverride;
         }
+        
+        if (!utWithCallbacks) {
+            Map<QName, Object> profiles = new HashMap<QName, Object>(3);
+            Processor processor = new UsernameTokenProcessorWithoutCallbacks();
+            profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+            profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+            return createSecurityEngine(profiles);
+        }
+        
         return secEngine;
     }
 

Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java Thu Oct 14 16:22:13 2010
@@ -28,9 +28,14 @@ import javax.xml.namespace.QName;
 import org.apache.cxf.Bus;
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
 import org.apache.cxf.systest.ws.wssec10.server.Server;
 import org.apache.cxf.systest.ws.wssec11.WSSecurity11Common;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
+
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -95,7 +100,16 @@ public class WSSecurity10Test extends Ab
                     ),
                     IPingService.class
                 );
+         
+            Client cl = ClientProxy.getClient(port);
             
+            HTTPConduit http = (HTTPConduit) cl.getConduit();
+             
+            HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
+            httpClientPolicy.setConnectionTimeout(0);
+            httpClientPolicy.setReceiveTimeout(0);
+             
+            http.setClient(httpClientPolicy);
             final String output = port.echo(INPUT);
             assertEquals(INPUT, output);
         }

Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java Thu Oct 14 16:22:13 2010
@@ -28,8 +28,12 @@ import javax.xml.namespace.QName;
 import org.apache.cxf.Bus;
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
 import org.apache.cxf.systest.ws.wssec10.server.AuthorizedServer;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -42,6 +46,7 @@ import wssec.wssec10.PingService;
  *
  */
 public class WSSecurity10UsernameAuthorizationTest extends AbstractBusClientServerTestBase {
+    static final String SSL_PORT = allocatePort(AuthorizedServer.class, 1);
     static final String PORT = allocatePort(AuthorizedServer.class);
 
     private static final String INPUT = "foo";
@@ -58,9 +63,9 @@ public class WSSecurity10UsernameAuthori
     }
 
     @Test
-    public void testClientServerAuthorized() {
+    public void testClientServerUTOnlyAuthorized() {
 
-        IPingService port = getPort(
+        IPingService port = getUTOnlyPort(
             "org/apache/cxf/systest/ws/wssec10/client/client_restricted.xml", false);
         
         final String output = port.echo(INPUT);
@@ -68,9 +73,9 @@ public class WSSecurity10UsernameAuthori
     }
     
     @Test
-    public void testClientServerUnauthorized() {
+    public void testClientServerUTOnlyUnauthorized() {
 
-        IPingService port = getPort(
+        IPingService port = getUTOnlyPort(
             "org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml", true);
         
         try {
@@ -81,7 +86,48 @@ public class WSSecurity10UsernameAuthori
         }
     }
     
-    private static IPingService getPort(String configName, boolean hashed) {
+    @Test
+    public void testClientServerComplexPolicyAuthorized() {
+
+        IPingService port = getComplexPolicyPort(
+            "org/apache/cxf/systest/ws/wssec10/client/client_restricted.xml");
+        
+        final String output = port.echo(INPUT);
+        assertEquals(INPUT, output);
+    }
+    
+    @Test
+    public void testClientServerComplexPolicyUnauthorized() {
+
+        IPingService port = getComplexPolicyPort(
+            "org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml");
+        
+        try {
+            port.echo(INPUT);
+            fail("Frank is unauthorized");
+        } catch (Exception ex) {
+            assertEquals("Unauthorized", ex.getMessage());
+        }
+    }
+    
+    private static IPingService getComplexPolicyPort(String configName) {
+        Bus bus = new SpringBusFactory().createBus(configName);
+        
+        BusFactory.setDefaultBus(bus);
+        BusFactory.setThreadDefaultBus(bus);
+        PingService svc = new PingService(getWsdlLocation("UserNameOverTransport"));
+        final IPingService port = 
+            svc.getPort(
+                new QName(
+                    "http://WSSec/wssec10",
+                    "UserNameOverTransport" + "_IPingService"
+                ),
+                IPingService.class
+            );
+        return port;
+    }
+    
+    private static IPingService getUTOnlyPort(String configName, boolean hashed) {
         Bus bus = new SpringBusFactory().createBus(configName);
         
         BusFactory.setDefaultBus(bus);
@@ -109,4 +155,19 @@ public class WSSecurity10UsernameAuthori
     }
 
     
+    private static URL getWsdlLocation(String portPrefix) {
+        try {
+            if ("UserNameOverTransport".equals(portPrefix)) {
+                return new URL("https://localhost:" + SSL_PORT + "/" + portPrefix + "?wsdl");
+            } else if ("MutualCertificate10SignEncrypt".equals(portPrefix)) {
+                return new URL("http://localhost:" + PORT + "/" + portPrefix + "?wsdl");
+            } else if ("MutualCertificate10SignEncryptRsa15TripleDes".equals(portPrefix)) {
+                return new URL("http://localhost:" + PORT + "/" + portPrefix + "?wsdl");
+            }
+        } catch (MalformedURLException mue) {
+            return null;
+        }
+        return null;
+    }
+    
 }

Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml Thu Oct 14 16:22:13 2010
@@ -47,4 +47,21 @@
         </jaxws:properties>
     </jaxws:client>
 
+    <jaxws:client name="{http://WSSec/wssec10}UserNameOverTransport_IPingService" createdFromAPI="true">
+        <jaxws:properties>
+            <entry key="ws-security.username" value="Frank"/>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.wssec10.client.UTPasswordCallback"/>
+        </jaxws:properties>
+    </jaxws:client>
+    
+    <http:conduit name="https://.*/UserNameOverTransport.*">
+        <http:tlsClientParameters disableCNCheck="true">
+            <sec:keyManagers keyPassword="password">
+                <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/alice.jks"/>
+            </sec:keyManagers>
+            <sec:trustManagers>
+                <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/bob.jks"/>
+            </sec:trustManagers>
+        </http:tlsClientParameters>
+    </http:conduit>
 </beans>

Added: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java (added)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,56 @@
+/**
+ * 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.ws.wssec10.server;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.common.security.SimplePrincipal;
+import org.apache.cxf.common.security.UsernameToken;
+import org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor;
+
+public class SimpleUsernameTokenInterceptor extends AbstractUsernameTokenInInterceptor {
+    
+    protected Subject createSubject(UsernameToken ut) {
+        return createSubject(ut.getName(), ut.getPassword(), ut.isHashed(),
+                             ut.getNonce(), ut.getCreatedTime());
+    }
+    
+    protected Subject createSubject(String name, 
+                                    String password, 
+                                    boolean isDigest,
+                                    String nonce,
+                                    String created) throws SecurityException {
+        Subject subject = new Subject();
+        
+        // delegate to the external security system if possible
+        
+        // authenticate the user somehow
+        subject.getPrincipals().add(new SimplePrincipal(name));
+        
+        // add roles this user is in
+        String roleName = "Alice".equals(name) ? "developers" : "pms";
+        subject.getPrincipals().add(new SimpleGroup(roleName, name));
+        subject.setReadOnly();
+        return subject;
+    }
+    
+}
+
+

Propchange: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml Thu Oct 14 16:22:13 2010
@@ -39,6 +39,34 @@
     ">
     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
     
+    <!-- -->
+    <!-- Any services listening on port 9001 must use the following -->
+    <!-- Transport Layer Security (TLS) settings -->
+    <!-- -->
+    <httpj:engine-factory id="tls-settings">
+        <httpj:engine port="${testutil.ports.AuthorizedServer.1}">
+            <httpj:tlsServerParameters>
+                <sec:keyManagers keyPassword="password">
+                    <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/bob.jks"/>
+                </sec:keyManagers>
+                <sec:trustManagers>
+                    <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/alice.jks"/>
+                </sec:trustManagers> 
+
+                <!--
+                <sec:cipherSuitesFilter>
+                    <sec:include>.*_EXPORT_.*</sec:include>
+                    <sec:include>.*_EXPORT1024_.*</sec:include>
+                    <sec:include>.*_WITH_DES_.*</sec:include>
+                    <sec:include>.*_WITH_NULL_.*</sec:include>
+                    <sec:exclude>.*_DH_anon_.*</sec:exclude>
+                </sec:cipherSuitesFilter>
+                <sec:clientAuthentication want="true" required="true"/>
+                -->
+            </httpj:tlsServerParameters>
+        </httpj:engine>
+    </httpj:engine-factory>
+    
     <cxf:bus>
         <cxf:features>
             <p:policies/>
@@ -53,7 +81,7 @@
 
     <bean id="customUTInterceptor" class="org.apache.cxf.systest.ws.wssec10.server.CustomUsernameTokenInterceptor"/>
 
-
+    <bean id="simpleUTInterceptor" class="org.apache.cxf.systest.ws.wssec10.server.SimpleUsernameTokenInterceptor"/>
     <bean id="authorizationInterceptor" class="org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor">
         <property name="methodRolesMap">
             <map>
@@ -90,4 +118,30 @@
      
     </jaxws:endpoint>
     
+    <!-- -->
+    <!-- Scenario 3.1 -->
+    <!-- -->
+    <jaxws:endpoint 
+       id="UserNameOverTransport"
+       address="https://localhost:${testutil.ports.AuthorizedServer.1}/UserNameOverTransport" 
+       serviceName="interop:PingService"
+       endpointName="interop:UserNameOverTransport_IPingService"
+       implementor="org.apache.cxf.systest.ws.wssec10.server.UserNameOverTransportRestricted"
+       depends-on="tls-settings">
+        
+       <jaxws:properties>
+            <entry key="ws-security.username" value="Alice"/>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.wssec10.server.UTPasswordCallback"/>
+            
+            <!-- new property -->
+            <entry key="ws-security.ut.no-callbacks" value="true"/>
+        </jaxws:properties> 
+
+        <jaxws:inInterceptors>
+            <ref bean="simpleUTInterceptor"/>
+            <ref bean="authorizationInterceptor"/>
+       </jaxws:inInterceptors> 
+     
+    </jaxws:endpoint>
+        
 </beans>