You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2009/02/26 17:34:29 UTC

svn commit: r748200 - in /cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security: policy/interceptors/ policy/model/ tokenstore/ wss4j/policyhandlers/

Author: dkulp
Date: Thu Feb 26 16:34:26 2009
New Revision: 748200

URL: http://svn.apache.org/viewvc?rev=748200&view=rev
Log:
Implement "Cancel" for WS-SC server side
Use WS-Add Action header if SOAPAction not set (WCF doesn't send a soapaction)


Modified:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java Thu Feb 26 16:34:26 2009
@@ -70,7 +70,12 @@
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.policy.SP11Constants;
 import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.model.Binding;
+import org.apache.cxf.ws.security.policy.model.Header;
+import org.apache.cxf.ws.security.policy.model.ProtectionToken;
 import org.apache.cxf.ws.security.policy.model.SecureConversationToken;
+import org.apache.cxf.ws.security.policy.model.SignedEncryptedParts;
+import org.apache.cxf.ws.security.policy.model.SymmetricBinding;
 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.MemoryTokenStore;
@@ -317,7 +322,21 @@
         public SecureConversationInInterceptor() {
             super(Phase.PRE_PROTOCOL);
         }
-
+        private Binding getBinding(AssertionInfoMap aim) {
+            Collection<AssertionInfo> ais = aim.get(SP12Constants.SYMMETRIC_BINDING);
+            if (ais != null && !ais.isEmpty()) {
+                return (Binding)ais.iterator().next().getAssertion();
+            }
+            ais = aim.get(SP12Constants.ASYMMETRIC_BINDING);
+            if (ais != null && !ais.isEmpty()) {
+                return (Binding)ais.iterator().next().getAssertion();
+            }
+            ais = aim.get(SP12Constants.TRANSPORT_BINDING);
+            if (ais != null && !ais.isEmpty()) {
+                return (Binding)ais.iterator().next().getAssertion();
+            }
+            return null;
+        }
         public void handleMessage(SoapMessage message) throws Fault {
             AssertionInfoMap aim = message.get(AssertionInfoMap.class);
             // extract Assertion information
@@ -326,25 +345,35 @@
                 if (ais == null || ais.isEmpty()) {
                     return;
                 }
-                if (!isRequestor(message)) {
-                    String s = (String)message.get(SoapBindingConstants.SOAP_ACTION);
+                if (isRequestor(message)) {
+                    //client side should be checked on the way out
+                    for (AssertionInfo ai : ais) {
+                        ai.setAsserted(true);
+                    }                    
+                    return;
+                }
+                String s = (String)message.get(SoapBindingConstants.SOAP_ACTION);
+                String addNs = null;
+                AddressingProperties inProps = (AddressingProperties)message
+                    .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
+                if (inProps != null) {
+                    addNs = inProps.getNamespaceURI();
                     if (s == null) {
                         //MS/WCF doesn't put a soap action out for this, must check the headers
-                        AddressingProperties inProps = (AddressingProperties)message
-                            .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
-                        if (inProps != null) {
-                            s = inProps.getAction().getValue();
-                        }
+                        s = inProps.getAction().getValue();
                     }
+                }
+
+                if (s != null 
+                    && s.contains("/RST/SCT")
+                    && (s.startsWith(STSUtils.WST_NS_05_02)
+                        || s.startsWith(STSUtils.WST_NS_05_12))) {
 
-                    if (s != null 
-                        && s.contains("/RST/SCT")
-                        && (s.startsWith(STSUtils.WST_NS_05_02)
-                            || s.startsWith(STSUtils.WST_NS_05_12))) {
-
-                        SecureConversationToken tok = (SecureConversationToken)ais.iterator()
-                            .next().getAssertion();
-                        Policy pol = tok.getBootstrapPolicy();
+                    SecureConversationToken tok = (SecureConversationToken)ais.iterator()
+                        .next().getAssertion();
+                    Policy pol = tok.getBootstrapPolicy();
+                    if (s.endsWith("Cancel") || s.endsWith("/Renew")) {
+                        //Cancel and Renew just sign with the token
                         Policy p = new Policy();
                         ExactlyOne ea = new ExactlyOne();
                         p.addPolicyComponent(ea);
@@ -352,23 +381,50 @@
                         PolicyAssertion ass = getAddressingPolicy(aim, false);
                         all.addPolicyComponent(ass);
                         ea.addPolicyComponent(all);
-                        pol = p.merge(pol);
+                        SymmetricBinding binding = new SymmetricBinding(SP12Constants.INSTANCE);
+                        ProtectionToken token = new ProtectionToken(SP12Constants.INSTANCE);
+                        token.setToken(new SecureConversationToken(SP12Constants.INSTANCE));
+                        binding.setProtectionToken(token);
+                        binding.setEntireHeadersAndBodySignatures(true);
+                        
+                        Binding origBinding = getBinding(aim);
+                        binding.setAlgorithmSuite(origBinding.getAlgorithmSuite());
+                        all.addPolicyComponent(binding);
                         
-                        //setup SCT endpoint and forward to it.
-                        unmapSecurityProps(message);
-                        String ns = STSUtils.WST_NS_05_12;
-                        if (s.startsWith(STSUtils.WST_NS_05_02)) {
-                            ns = STSUtils.WST_NS_05_02;
+                        SignedEncryptedParts parts = new SignedEncryptedParts(true, 
+                                                                              SP12Constants.INSTANCE);
+                        parts.setBody(true);
+                        if (addNs != null) {
+                            parts.addHeader(new Header("To", addNs));
+                            parts.addHeader(new Header("From", addNs));
+                            parts.addHeader(new Header("FaultTo", addNs));
+                            parts.addHeader(new Header("ReplyTO", addNs));
+                            parts.addHeader(new Header("MessageID", addNs));
+                            parts.addHeader(new Header("RelatesTo", addNs));
+                            parts.addHeader(new Header("Action", addNs));
                         }
-                        recalcEffectivePolicy(message, ns, pol);
+                        all.addPolicyComponent(parts);
+                        pol = p;
                     } else {
-                        message.getInterceptorChain().add(new SecureConversationTokenFinderInterceptor());
+                        Policy p = new Policy();
+                        ExactlyOne ea = new ExactlyOne();
+                        p.addPolicyComponent(ea);
+                        All all = new All();
+                        PolicyAssertion ass = getAddressingPolicy(aim, false);
+                        all.addPolicyComponent(ass);
+                        ea.addPolicyComponent(all);
+                        pol = p.merge(pol);
                     }
+                    
+                    //setup SCT endpoint and forward to it.
+                    unmapSecurityProps(message);
+                    String ns = STSUtils.WST_NS_05_12;
+                    if (s.startsWith(STSUtils.WST_NS_05_02)) {
+                        ns = STSUtils.WST_NS_05_02;
+                    }
+                    recalcEffectivePolicy(message, ns, pol);
                 } else {
-                    //client side should be checked on the way out
-                    for (AssertionInfo ai : ais) {
-                        ai.setAsserted(true);
-                    }                    
+                    message.getInterceptorChain().add(new SecureConversationTokenFinderInterceptor());
                 }
             }
         }
@@ -429,7 +485,7 @@
                 AddressingProperties inProps = (AddressingProperties)exchange.getInMessage()
                     .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
                 if (inProps != null) {
-                    AddressingProperties props = new AddressingPropertiesImpl();
+                    AddressingProperties props = new AddressingPropertiesImpl(inProps.getNamespaceURI());
                     AttributedURIType action = new AttributedURIType();
                     action.setValue(inProps.getAction().getValue().replace("/RST/", "/RSTR/"));
                     props.setAction(action);
@@ -440,90 +496,59 @@
                 MessageContentsList lst = (MessageContentsList)o;
                 DOMSource src = (DOMSource)lst.get(0);
                 Node nd = src.getNode();
-                Element el = null;
+                Element requestEl = null;
                 if (nd instanceof Document) {
-                    el = ((Document)nd).getDocumentElement();
+                    requestEl = ((Document)nd).getDocumentElement();
                 } else {
-                    el = (Element)nd;
+                    requestEl = (Element)nd;
                 }
-                String namespace = el.getNamespaceURI();
-                String prefix = el.getPrefix();
-                byte clientEntropy[] = null;
-                int keySize = 256;
-                int ttl = 300000;
-                String tokenType = null;
-                if ("RequestSecurityToken".equals(el.getLocalName())) {
+                String namespace = requestEl.getNamespaceURI();
+                String prefix = requestEl.getPrefix();
+                SecurityToken cancelToken = null;
+                if ("RequestSecurityToken".equals(requestEl.getLocalName())) {
                     try {
-                        el = DOMUtils.getFirstElement(el);
+                        W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+                        writer.setNsRepairing(true);
+                        if (STSUtils.WST_NS_05_12.equals(namespace)) {
+                            writer.writeStartElement(prefix, "RequestSecurityTokenResponseCollection",
+                                                     namespace);
+                        }
+                        writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
+                        
+                        String requestType = null;
+                        Element el = DOMUtils.getFirstElement(requestEl);
                         while (el != null) {
                             String localName = el.getLocalName();
                             if (namespace.equals(el.getNamespaceURI())) {
-                                if ("Entropy".equals(localName)) {
-                                    Element bs = DOMUtils.getFirstElement(el);
-                                    if (bs != null) {
-                                        clientEntropy = Base64.decode(bs.getTextContent());
-                                    }
-                                } else if ("KeySize".equals(localName)) {
-                                    keySize = Integer.parseInt(el.getTextContent());
-                                } else if ("TokenType".equals(localName)) {
-                                    tokenType = el.getTextContent();
+                                if ("RequestType".equals(localName)) {
+                                    requestType = el.getTextContent();
+                                } else if ("CancelTarget".equals(localName)) {
+                                    cancelToken = findCancelToken(exchange, el);
                                 }
                             }
                             
                             el = DOMUtils.getNextElement(el);
                         }
+                        if (requestType == null) {
+                            requestType = "/Issue";
+                        }
                         
-                        W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
-                        writer.setNsRepairing(true);
-                        writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
-                        writer.writeStartElement(prefix, "RequestedSecurityToken", namespace);
-                        SecurityContextToken sct =
-                            new SecurityContextToken(getWSCVersion(tokenType), writer.getDocument());
-                        
-                        Calendar created = Calendar.getInstance();
-                        Calendar expires = Calendar.getInstance();
-                        expires.setTimeInMillis(System.currentTimeMillis() + ttl);
-
-                        SecurityToken token = new SecurityToken(sct.getIdentifier(), created, expires);
-                        token.setToken(sct.getElement());
-                        token.setTokenType(WSConstants.WSC_SCT);
-                        
-                        writer.getCurrentNode().appendChild(sct.getElement());
-                        writer.writeEndElement();        
-                        
-                        writer.writeStartElement(prefix, "RequestedAttachedReference", namespace);
-                        token.setAttachedReference(writeSecurityTokenReference(writer,
-                                                                               "#" + sct.getID(), 
-                                                                               tokenType));
-                        writer.writeEndElement();
-                        
-                        writer.writeStartElement(prefix, "RequestedUnattachedReference", namespace);
-                        token.setUnattachedReference(writeSecurityTokenReference(writer,
-                                                                                 sct.getIdentifier(),
-                                                                                 tokenType));
-                        writer.writeEndElement();
-                        
-                        XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
-                        writer.writeStartElement(prefix, "Lifetime", namespace);
-                        writer.writeNamespace("wsu", WSConstants.WSU_NS);
-                        writer.writeStartElement("wsu", "Created", WSConstants.WSU_NS);
-                        writer.writeCharacters(fmt.format(created.getTime()));
-                        writer.writeEndElement();
-                        
-                        writer.writeStartElement("wsu", "Expires", WSConstants.WSU_NS);
-                        writer.writeCharacters(fmt.format(expires.getTime()));
-                        writer.writeEndElement();
-                        writer.writeEndElement();
-
-                        byte[] secret = writeProofToken(prefix, 
-                                                        namespace,
-                                                        writer,
-                                                        clientEntropy, 
-                                                        keySize);
-                        token.setSecret(secret);
-                        ((TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
-                                .getProperty(TokenStore.class.getName())).add(token);
+                        if (requestType.endsWith("/Issue")) { 
+                            doIssue(requestEl, exchange, writer, prefix, namespace);
+                        } else if (requestType.endsWith("/Cancel")) {
+                            TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+                                .getProperty(TokenStore.class.getName());
+                            cancelToken.setState(SecurityToken.State.CANCELLED);
+                            store.update(cancelToken);
+                            writer.writeEmptyElement(prefix, "RequestedTokenCancelled", namespace);
+                            exchange.put(SecurityConstants.TOKEN, cancelToken);
+                        } else if (requestType.endsWith("/Renew")) {
+                            //REVISIT - implement
+                        }
                         writer.writeEndElement();
+                        if (STSUtils.WST_NS_05_12.equals(namespace)) {
+                            writer.writeEndElement();
+                        }
                         return new MessageContentsList(new DOMSource(writer.getDocument()));
                     } catch (RuntimeException ex) {
                         throw ex;
@@ -531,10 +556,94 @@
                         throw new Fault(ex);
                     }
                 } else {
-                    throw new Fault("Unknown SecureConversation request type: " + el.getLocalName(), LOG);
+                    throw new Fault("Unknown SecureConversation element: " + requestEl.getLocalName(), LOG);
                 }
             }
 
+            private void doIssue(Element requestEl,
+                                 Exchange exchange, W3CDOMStreamWriter writer,
+                                 String prefix, String namespace) 
+                throws Exception {
+                byte clientEntropy[] = null;
+                int keySize = 256;
+                int ttl = 300000;
+                String tokenType = null;
+                Element el = DOMUtils.getFirstElement(requestEl);
+                while (el != null) {
+                    String localName = el.getLocalName();
+                    if (namespace.equals(el.getNamespaceURI())) {
+                        if ("Entropy".equals(localName)) {
+                            Element bs = DOMUtils.getFirstElement(el);
+                            if (bs != null) {
+                                clientEntropy = Base64.decode(bs.getTextContent());
+                            }
+                        } else if ("KeySize".equals(localName)) {
+                            keySize = Integer.parseInt(el.getTextContent());
+                        } else if ("TokenType".equals(localName)) {
+                            tokenType = el.getTextContent();
+                        }
+                    }
+                    
+                    el = DOMUtils.getNextElement(el);
+                }
+                
+                writer.writeStartElement(prefix, "RequestedSecurityToken", namespace);
+                SecurityContextToken sct =
+                    new SecurityContextToken(getWSCVersion(tokenType), writer.getDocument());
+                
+                Calendar created = Calendar.getInstance();
+                Calendar expires = Calendar.getInstance();
+                expires.setTimeInMillis(System.currentTimeMillis() + ttl);
+
+                SecurityToken token = new SecurityToken(sct.getIdentifier(), created, expires);
+                token.setToken(sct.getElement());
+                token.setTokenType(WSConstants.WSC_SCT);
+                
+                writer.getCurrentNode().appendChild(sct.getElement());
+                writer.writeEndElement();        
+                
+                writer.writeStartElement(prefix, "RequestedAttachedReference", namespace);
+                token.setAttachedReference(writeSecurityTokenReference(writer,
+                                                                       "#" + sct.getID(), 
+                                                                       tokenType));
+                writer.writeEndElement();
+                
+                writer.writeStartElement(prefix, "RequestedUnattachedReference", namespace);
+                token.setUnattachedReference(writeSecurityTokenReference(writer,
+                                                                         sct.getIdentifier(),
+                                                                         tokenType));
+                writer.writeEndElement();
+                
+                XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
+                writer.writeStartElement(prefix, "Lifetime", namespace);
+                writer.writeNamespace("wsu", WSConstants.WSU_NS);
+                writer.writeStartElement("wsu", "Created", WSConstants.WSU_NS);
+                writer.writeCharacters(fmt.format(created.getTime()));
+                writer.writeEndElement();
+                
+                writer.writeStartElement("wsu", "Expires", WSConstants.WSU_NS);
+                writer.writeCharacters(fmt.format(expires.getTime()));
+                writer.writeEndElement();
+                writer.writeEndElement();
+
+                byte[] secret = writeProofToken(prefix, 
+                                                namespace,
+                                                writer,
+                                                clientEntropy, 
+                                                keySize);
+                token.setSecret(secret);
+                ((TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+                        .getProperty(TokenStore.class.getName())).add(token);
+            }
+
+            private SecurityToken findCancelToken(Exchange exchange, Element el) throws WSSecurityException {
+                SecurityTokenReference ref = new SecurityTokenReference(DOMUtils.getFirstElement(el));
+                String uri = ref.getReference().getURI();
+                TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+                        .getProperty(TokenStore.class.getName());
+                return store.getToken(uri);
+            }
+
         }
     }
     private static byte[] writeProofToken(String prefix, 
@@ -551,7 +660,7 @@
             random.nextBytes(secret);
             
             writer.writeStartElement(prefix, "BinarySecret", namespace);
-            writer.writeAttribute("", namespace + "/Nonce");
+            writer.writeAttribute("Type", namespace + "/Nonce");
             writer.writeCharacters(Base64.encode(secret));
             writer.writeEndElement();
         } else {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java Thu Feb 26 16:34:26 2009
@@ -23,6 +23,14 @@
     private String name;
     private String namespace;
 
+    public Header() {
+    }
+    
+    public Header(String nm, String ns) {
+        name = nm;
+        namespace = ns;
+    }
+    
     /**
      * @return Returns the name.
      */

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java Thu Feb 26 16:34:26 2009
@@ -38,7 +38,7 @@
  * 
  */
 public class SecurityToken {
-    enum State {
+    public enum State {
         UNKNOWN,
         ISSUED, 
         EXPIRED, 

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java Thu Feb 26 16:34:26 2009
@@ -669,7 +669,6 @@
             
             sig.setCustomTokenId(sigTokId);
             sig.setSecretKey(tok.getSecret());
-            sig.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getAsymmetricSignature());
             sig.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getSymmetricSignature());
             Crypto crypto = null;
             if (sbinding.getProtectionToken() != null) {