cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1130195 - in /cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security: ./ policy/interceptors/ trust/ trust/delegation/
Date Wed, 01 Jun 2011 15:47:33 GMT
Author: coheigea
Date: Wed Jun  1 15:47:33 2011
New Revision: 1130195

URL: http://svn.apache.org/viewvc?rev=1130195&view=rev
Log:
[CXF-3565] - Support pluggable way of configuring WS-Trust ActAs and OnBehalfOf behaviour

Added:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/DelegationCallback.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/WSSUsernameCallbackHandler.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/policy/interceptors/IssuedTokenInterceptorProvider.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java

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=1130195&r1=1130194&r2=1130195&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
Wed Jun  1 15:47:33 2011
@@ -105,6 +105,8 @@ public final class SecurityConstants {
     public static final String STS_TOKEN_DO_CANCEL = "ws-security.sts.token.do.cancel";
     
     public static final String STS_TOKEN_ACT_AS = "ws-security.sts.token.act-as";
+    
+    public static final String STS_TOKEN_ON_BEHALF_OF = "ws-security.sts.token.on-behalf-of";
 
     public static final Set<String> ALL_PROPERTIES;
     
@@ -118,7 +120,7 @@ public final class SecurityConstants {
             STS_TOKEN_ACT_AS, STS_TOKEN_USERNAME, STS_TOKEN_USE_CERT_FOR_KEYINFO,
             SAML1_TOKEN_VALIDATOR, SAML2_TOKEN_VALIDATOR, TIMESTAMP_TOKEN_VALIDATOR,
             SIGNATURE_TOKEN_VALIDATOR, IS_BSP_COMPLIANT, TIMESTAMP_FUTURE_TTL,
-            BST_TOKEN_VALIDATOR, SAML_CALLBACK_HANDLER
+            BST_TOKEN_VALIDATOR, SAML_CALLBACK_HANDLER, STS_TOKEN_ON_BEHALF_OF
         }));
         ALL_PROPERTIES = Collections.unmodifiableSet(s);
     }

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java?rev=1130195&r1=1130194&r2=1130195&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java
(original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java
Wed Jun  1 15:47:33 2011
@@ -123,10 +123,19 @@ public class IssuedTokenInterceptorProvi
                         }
                         synchronized (client) {
                             try {
-                                // Transpose ActAs info from original request to the STS
client.
-                                client.setActAs(
-                                    message.getContextualProperty(SecurityConstants.STS_TOKEN_ACT_AS));
+                                // Transpose ActAs/OnBehalfOf info from original request
to the STS client.
+                                Object token = 
+                                    message.getContextualProperty(SecurityConstants.STS_TOKEN_ACT_AS);
+                                if (token != null) {
+                                    client.setActAs(token);
+                                }
+                                token = 
+                                    message.getContextualProperty(SecurityConstants.STS_TOKEN_ON_BEHALF_OF);
+                                if (token != null) {
+                                    client.setOnBehalfOf(token);
+                                }
 
+                                client.setMessage(message);
                                 client.setTrust(getTrust10(aim));
                                 client.setTrust(getTrust13(aim));
                                 client.setTemplate(itok.getRstTemplate());
@@ -188,6 +197,7 @@ public class IssuedTokenInterceptorProvi
             }
             return (Trust13)ais.iterator().next().getAssertion();
         }
+        
     }
     
     static class IssuedTokenInInterceptor extends AbstractPhaseInterceptor<Message>
{

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java?rev=1130195&r1=1130194&r2=1130195&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
(original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
Wed Jun  1 15:47:33 2011
@@ -35,6 +35,7 @@ import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
@@ -94,6 +95,7 @@ import org.apache.cxf.ws.security.policy
 import org.apache.cxf.ws.security.policy.model.Trust10;
 import org.apache.cxf.ws.security.policy.model.Trust13;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.trust.delegation.DelegationCallback;
 import org.apache.cxf.wsdl11.WSDLServiceFactory;
 import org.apache.neethi.All;
 import org.apache.neethi.ExactlyOne;
@@ -141,7 +143,7 @@ public class STSClient implements Config
     AlgorithmSuite algorithmSuite;
     String namespace = STSUtils.WST_NS_05_12;
     String addressingNamespace;
-    Element onBehalfOfElement;
+    Object onBehalfOf;
 
     boolean useCertificateForConfirmationKeyInfo;
     boolean isSecureConv;
@@ -151,6 +153,7 @@ public class STSClient implements Config
     String tokenType;
     String keyType;
     boolean sendKeyType = true;
+    Message message;
 
     Map<String, Object> ctx = new HashMap<String, Object>();
     
@@ -179,6 +182,10 @@ public class STSClient implements Config
     public void setLocation(String location) {
         this.location = location;
     }
+    
+    public void setMessage(Message message) {
+        this.message = message;
+    }
 
     /**
      * Sets the WS-P policy that is applied to communications between this client and the
remote server
@@ -320,10 +327,15 @@ public class STSClient implements Config
         this.keyType = keyType;
     }
     
+    @Deprecated
     public void setOnBehalfOfElement(Element onBehalfOfElement) {
-        this.onBehalfOfElement = onBehalfOfElement;
+        this.onBehalfOf = onBehalfOfElement;
     }
 
+    public void setOnBehalfOf(Object onBehalfOf) {
+        this.onBehalfOf = onBehalfOf;
+    }
+    
     /**
      * Indicate whether to use the signer's public X509 certificate for the subject confirmation
key info 
      * when creating a RequestsSecurityToken message. If the property is set to 'false',
only the public key 
@@ -609,11 +621,32 @@ public class STSClient implements Config
         writer.writeEndElement();
     }
     
-    private void addOnBehalfOf(W3CDOMStreamWriter writer) throws XMLStreamException  {
-        if (onBehalfOfElement != null) {
-            writer.writeStartElement("wst", "OnBehalfOf", namespace);
-            StaxUtils.copy(onBehalfOfElement, writer);
-            writer.writeEndElement();
+    private void addOnBehalfOf(W3CDOMStreamWriter writer) throws Exception {
+        if (this.onBehalfOf != null) {
+            final boolean isString = this.onBehalfOf instanceof String;
+            final boolean isElement = this.onBehalfOf instanceof Element; 
+            final boolean isCallbackHandler = this.onBehalfOf instanceof CallbackHandler;
+            if (isString || isElement || isCallbackHandler) {
+                final Element tokenElement;
+                
+                if (isString) {
+                    final Document acAsDoc =
+                        DOMUtils.readXml(new StringReader((String) this.onBehalfOf));
+                    tokenElement = acAsDoc.getDocumentElement();
+                } else if (isElement) {
+                    tokenElement = (Element)this.onBehalfOf;
+                } else {
+                    DelegationCallback callback = new DelegationCallback(message);
+                    ((CallbackHandler)onBehalfOf).handle(new Callback[]{callback});
+                    tokenElement = callback.getToken();
+                }
+                
+                if (tokenElement != null) {
+                    writer.writeStartElement("wst", "OnBehalfOf", namespace);
+                    StaxUtils.copy(tokenElement, writer);
+                    writer.writeEndElement();
+                }
+            }
         }
     }
     
@@ -914,27 +947,27 @@ public class STSClient implements Config
         if (this.actAs != null) {
             final boolean isString = this.actAs instanceof String;
             final boolean isElement = this.actAs instanceof Element; 
-            if (isString || isElement) {
-                final Element actAsEl;
+            final boolean isCallbackHandler = this.actAs instanceof CallbackHandler;
+            if (isString || isElement || isCallbackHandler) {
+                final Element tokenElement;
                 
                 if (isString) {
                     final Document acAsDoc =
                         DOMUtils.readXml(new StringReader((String) this.actAs));
-                    actAsEl = acAsDoc.getDocumentElement();
+                    tokenElement = acAsDoc.getDocumentElement();
+                } else if (isElement) {
+                    tokenElement = (Element) this.actAs;
                 } else {
-                    actAsEl = (Element) this.actAs;
+                    DelegationCallback callback = new DelegationCallback(message);
+                    ((CallbackHandler)actAs).handle(new Callback[]{callback});
+                    tokenElement = callback.getToken();
                 }
                 
-                writer.writeStartElement(STSUtils.WST_NS_08_02, "ActAs");
-                
-                // Unlikely to ever be otherwise, but still prudent to check.
-                if (actAsEl.getOwnerDocument() != writer.getDocument()) {
-                    writer.getDocument().adoptNode(actAsEl);
+                if (tokenElement != null) {
+                    writer.writeStartElement(STSUtils.WST_NS_08_02, "ActAs");
+                    StaxUtils.copy(tokenElement, writer);
+                    writer.writeEndElement();
                 }
-                
-                writer.getCurrentNode().appendChild(actAsEl);
-                
-                writer.writeEndElement();
             }
         }
     }

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/DelegationCallback.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/DelegationCallback.java?rev=1130195&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/DelegationCallback.java
(added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/DelegationCallback.java
Wed Jun  1 15:47:33 2011
@@ -0,0 +1,64 @@
+/**
+ * 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.trust.delegation;
+
+import javax.security.auth.callback.Callback;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.message.Message;
+
+/**
+ * This Callback class provides a pluggable way of performing delegation. A CallbackHandler
+ * instance will be supplied with this class, which contains a reference to the current
+ * Message. The CallbackHandler implementation is required to set the token Element to be
+ * sent in the request. 
+ */
+public class DelegationCallback implements Callback {
+    
+    private Element token;
+    
+    private Message currentMessage;
+    
+    public DelegationCallback() {
+        //
+    }
+    
+    public DelegationCallback(Message currentMessage) {
+        this.currentMessage = currentMessage;
+    }
+    
+    public void setToken(Element token) {
+        this.token = token;
+    }
+    
+    public Element getToken() {
+        return token;
+    }
+    
+    public void setCurrentMessage(Message currentMessage) {
+        this.currentMessage = currentMessage;
+    }
+    
+    public Message getCurrentMessage() {
+        return currentMessage;
+    }
+    
+}

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java?rev=1130195&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java
(added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java
Wed Jun  1 15:47:33 2011
@@ -0,0 +1,113 @@
+/**
+ * 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.trust.delegation;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.List;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+
+/**
+ * This CallbackHandler implementation obtains the previously received message from a 
+ * DelegationCallback object, and obtains a received token 
+ * (SAML/UsernameToken/BinarySecurityToken) from it to be used as the delegation token.
+ */
+public class ReceivedTokenCallbackHandler implements CallbackHandler {
+    
+    @SuppressWarnings("unchecked")
+    public void handle(Callback[] callbacks)
+        throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof DelegationCallback) {
+                DelegationCallback callback = (DelegationCallback) callbacks[i];
+                Message message = callback.getCurrentMessage();
+                
+                if (message != null 
+                    && message.get(PhaseInterceptorChain.PREVIOUS_MESSAGE) != null)
{
+                    WeakReference<SoapMessage> wr = 
+                        (WeakReference<SoapMessage>)
+                            message.get(PhaseInterceptorChain.PREVIOUS_MESSAGE);
+                    SoapMessage previousSoapMessage = wr.get();
+                    Element token = getTokenFromMessage(previousSoapMessage);
+                    callback.setToken(token);
+                }
+                
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+            }
+        }
+    }
+    
+    private Element getTokenFromMessage(SoapMessage soapMessage) {
+        List<WSHandlerResult> results = 
+            CastUtils.cast((List<?>)soapMessage.get(WSHandlerConstants.RECV_RESULTS));
+        if (results != null) {
+            for (WSHandlerResult rResult : results) {
+                Element token = findToken(rResult.getResults());
+                if (token != null) {
+                    return token;
+                }
+            }
+        }
+        return null;
+    }
+    
+    private Element findToken(
+        List<WSSecurityEngineResult> wsSecEngineResults
+    ) {
+        for (WSSecurityEngineResult wser : wsSecEngineResults) {
+            Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+            if (actInt.intValue() == WSConstants.ST_SIGNED
+                || actInt.intValue() == WSConstants.ST_UNSIGNED) {
+                AssertionWrapper assertion = 
+                    (AssertionWrapper)wser.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+                return assertion.getElement();
+            } else if (actInt.intValue() == WSConstants.UT
+                || actInt.intValue() == WSConstants.UT_NOPASSWORD) {
+                UsernameToken token =
+                    (UsernameToken)wser.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
+                return token.getElement();
+            } else if (actInt.intValue() == WSConstants.BST) {
+                BinarySecurity token = 
+                    (BinarySecurity)wser.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+                return token.getElement();
+            }
+        }
+        return null;
+    }
+    
+}

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/WSSUsernameCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/WSSUsernameCallbackHandler.java?rev=1130195&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/WSSUsernameCallbackHandler.java
(added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/WSSUsernameCallbackHandler.java
Wed Jun  1 15:47:33 2011
@@ -0,0 +1,78 @@
+/**
+ * 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.trust.delegation;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.message.WSSecUsernameToken;
+
+/**
+ * This CallbackHandler implementation obtains a username via the jaxws property 
+ * "ws-security.username", as defined in SecurityConstants, and creates a wss UsernameToken

+ * (with no password) to be used as the delegation token.
+ */
+public class WSSUsernameCallbackHandler implements CallbackHandler {
+    
+    public void handle(Callback[] callbacks)
+        throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof DelegationCallback) {
+                DelegationCallback callback = (DelegationCallback) callbacks[i];
+                Message message = callback.getCurrentMessage();
+                
+                String username = 
+                    (String)message.getContextualProperty(SecurityConstants.USERNAME);
+                if (username != null) {
+                    Node contentNode = message.getContent(Node.class);
+                    Document doc = null;
+                    if (contentNode != null) {
+                        doc = contentNode.getOwnerDocument();
+                    } else {
+                        doc = DOMUtils.createDocument();
+                    }
+                    Element token = createWSSEUsernameToken(username, doc);
+                    callback.setToken(token);
+                }
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+            }
+        }
+    }
+    
+    private Element createWSSEUsernameToken(String username, Document doc) {
+        WSSecUsernameToken builder = new WSSecUsernameToken();
+        builder.setPasswordType(null);
+        builder.setUserInfo(username, null);
+        builder.prepare(doc);
+        return builder.getUsernameTokenElement();
+    }
+    
+}



Mime
View raw message