cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1160689 - in /cxf/trunk: rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/ rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/ systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/
Date Tue, 23 Aug 2011 13:47:51 GMT
Author: sergeyb
Date: Tue Aug 23 13:47:51 2011
New Revision: 1160689

URL: http://svn.apache.org/viewvc?rev=1160689&view=rev
Log:
[CXF-3587] Adding SAML handlers for passing tokens inside custom xml envelopes

Added:
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
  (with props)
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
  (with props)
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java
  (with props)
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java
  (with props)
Modified:
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlOutInterceptor.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecOutInterceptor.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInHandler.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInInterceptor.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/server.xml

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java
Tue Aug 23 13:47:51 2011
@@ -33,6 +33,7 @@ import javax.ws.rs.WebApplicationExcepti
 import javax.ws.rs.core.Response;
 
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.DOMUtils;
@@ -70,7 +71,7 @@ public abstract class AbstractSamlInHand
         samlValidator = validator;
     }
     
-    public void validateToken(Message message, InputStream tokenStream) {
+    protected void validateToken(Message message, InputStream tokenStream) {
         
         Document doc = null;
         try {
@@ -78,9 +79,13 @@ public abstract class AbstractSamlInHand
         } catch (Exception ex) {
             throwFault("Assertion can not be read as XML document", ex);
         }
+        validateToken(message, doc.getDocumentElement());
         
+    }
+
+    protected void validateToken(Message message, Element tokenElement) {
         try {
-            AssertionWrapper assertion = new AssertionWrapper(doc.getDocumentElement());
+            AssertionWrapper assertion = new AssertionWrapper(tokenElement);
             if (assertion.isSigned()) {
                 RequestData data = new RequestData();
                 WSSConfig cfg = WSSConfig.getNewInstance(); 
@@ -122,7 +127,8 @@ public abstract class AbstractSamlInHand
             throwFault("Assertion can not be validated", ex);
         }
     }
-
+    
+    
     private Certificate[] getTLSCertificates(Message message) {
         TLSSessionInfo tlsInfo = message.get(TLSSessionInfo.class);
         return tlsInfo != null ? tlsInfo.getPeerCertificates() : null;

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlOutInterceptor.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlOutInterceptor.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlOutInterceptor.java
Tue Aug 23 13:47:51 2011
@@ -18,34 +18,19 @@
  */
 package org.apache.cxf.rs.security.saml;
 
-import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
-import java.util.logging.Logger;
 
-import javax.security.auth.callback.CallbackHandler;
-
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.Base64Exception;
 import org.apache.cxf.common.util.Base64Utility;
-import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.rs.security.common.CryptoLoader;
-import org.apache.cxf.rs.security.common.SecurityUtils;
-import org.apache.cxf.ws.security.SecurityConstants;
-import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSConfig;
-import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.saml.ext.AssertionWrapper;
-import org.apache.ws.security.saml.ext.SAMLParms;
 
 public abstract class AbstractSamlOutInterceptor extends AbstractPhaseInterceptor<Message>
{
-    private static final Logger LOG = 
-        LogUtils.getL7dLogger(AbstractSamlOutInterceptor.class);
     
     static {
         WSSConfig.init();
@@ -62,40 +47,7 @@ public abstract class AbstractSamlOutInt
     }
     
     protected AssertionWrapper createAssertion(Message message) throws Fault {
-        CallbackHandler handler = SecurityUtils.getCallbackHandler(
-             message, this.getClass(), SecurityConstants.SAML_CALLBACK_HANDLER);
-        SAMLParms samlParms = new SAMLParms();
-        samlParms.setCallbackHandler(handler);
-        try {
-            AssertionWrapper assertion = new AssertionWrapper(samlParms);
-            boolean selfSignAssertion = 
-                MessageUtils.getContextualBoolean(
-                    message, SecurityConstants.SELF_SIGN_SAML_ASSERTION, false
-                );
-            if (selfSignAssertion) {
-                //--- This code will be moved to a common utility class
-                Crypto crypto = new CryptoLoader().getCrypto(message, 
-                                          SecurityConstants.SIGNATURE_CRYPTO,
-                                          SecurityConstants.SIGNATURE_PROPERTIES);
-                
-                String user = 
-                    SecurityUtils.getUserName(message, crypto, SecurityConstants.SIGNATURE_USERNAME);
-                if (StringUtils.isEmpty(user)) {
-                    return assertion;
-                }
-        
-                String password = 
-                    SecurityUtils.getPassword(message, user, WSPasswordCallback.SIGNATURE,
this.getClass());
-                
-                assertion.signAssertion(user, password, crypto, false);
-            }
-            return assertion;
-        } catch (Exception ex) {
-            StringWriter sw = new StringWriter();
-            ex.printStackTrace(new PrintWriter(sw));
-            LOG.warning(sw.toString());
-            throw new Fault(new RuntimeException(ex.getMessage() + ", stacktrace: " + sw.toString()));
-        }
+        return SAMLUtils.createAssertion(message);
         
     }
     

Added: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java?rev=1160689&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
(added)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
Tue Aug 23 13:47:51 2011
@@ -0,0 +1,86 @@
+/**
+ * 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.rs.security.saml;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.rs.security.common.CryptoLoader;
+import org.apache.cxf.rs.security.common.SecurityUtils;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+import org.apache.ws.security.saml.ext.SAMLParms;
+
+public final class SAMLUtils {
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(SAMLUtils.class);
+    
+    private SAMLUtils() {
+        
+    }
+    
+    public static AssertionWrapper createAssertion(Message message) throws Fault {
+        CallbackHandler handler = SecurityUtils.getCallbackHandler(
+             message, SAMLUtils.class, SecurityConstants.SAML_CALLBACK_HANDLER);
+        SAMLParms samlParms = new SAMLParms();
+        samlParms.setCallbackHandler(handler);
+        try {
+            AssertionWrapper assertion = new AssertionWrapper(samlParms);
+            boolean selfSignAssertion = 
+                MessageUtils.getContextualBoolean(
+                    message, SecurityConstants.SELF_SIGN_SAML_ASSERTION, false
+                );
+            if (selfSignAssertion) {
+                //--- This code will be moved to a common utility class
+                Crypto crypto = new CryptoLoader().getCrypto(message, 
+                                          SecurityConstants.SIGNATURE_CRYPTO,
+                                          SecurityConstants.SIGNATURE_PROPERTIES);
+                
+                String user = 
+                    SecurityUtils.getUserName(message, crypto, SecurityConstants.SIGNATURE_USERNAME);
+                if (StringUtils.isEmpty(user)) {
+                    return assertion;
+                }
+        
+                String password = 
+                    SecurityUtils.getPassword(message, user, WSPasswordCallback.SIGNATURE,

+                            SAMLUtils.class);
+                
+                assertion.signAssertion(user, password, crypto, false);
+            }
+            return assertion;
+        } catch (Exception ex) {
+            StringWriter sw = new StringWriter();
+            ex.printStackTrace(new PrintWriter(sw));
+            LOG.warning(sw.toString());
+            throw new Fault(new RuntimeException(ex.getMessage() + ", stacktrace: " + sw.toString()));
+        }
+        
+    }
+}

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java?rev=1160689&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
(added)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
Tue Aug 23 13:47:51 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.rs.security.saml;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import javax.ws.rs.core.Response;
+import javax.xml.stream.XMLStreamReader;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.W3CDOMStreamReader;
+
+public class SamlEnvelopedInHandler extends AbstractSamlInHandler {
+
+    private static final String SAML2_NS = "urn:oasis:names:tc:SAML:2.0:assertion";
+    private static final String SAML1_NS = "urn:oasis:names:tc:SAML:1.0:assertion";
+    private static final String SAML_ASSERTION = "Assertion";
+    public SamlEnvelopedInHandler() {
+    }
+    
+    public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
+        String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
+        if ("GET".equals(method)) {
+            return null;
+        }
+        
+        Document doc = null;
+        InputStream is = message.getContent(InputStream.class);
+        if (is != null) {
+            try {
+                doc = DOMUtils.readXml(new InputStreamReader(is, "UTF-8"));
+            } catch (Exception ex) {
+                throwFault("Invalid XML payload", ex);
+            }
+        } else {
+            XMLStreamReader reader = message.getContent(XMLStreamReader.class);
+            if (reader instanceof W3CDOMStreamReader) {
+                doc = ((W3CDOMStreamReader)reader).getDocument();
+            }
+        }
+        if (doc == null) {
+            throwFault("No payload is available", null);
+        }
+        Element samlElement = getNode(doc.getDocumentElement(),
+                SAML2_NS, SAML_ASSERTION);
+        if (samlElement == null) {
+            samlElement = getNode(doc.getDocumentElement(),
+                    SAML1_NS, SAML_ASSERTION);
+        }
+        if (samlElement == null) {
+            throwFault("SAML Assertion is not available", null);
+        }
+        validateToken(message, samlElement);
+        
+        doc.getDocumentElement().removeChild(samlElement);
+        Element actualBody = getActualBody(doc.getDocumentElement());
+        if (actualBody != null) {
+            Document newDoc = DOMUtils.createDocument();
+            newDoc.adoptNode(actualBody);
+            message.setContent(XMLStreamReader.class, 
+                    new W3CDOMStreamReader(actualBody));
+            message.setContent(InputStream.class, null);
+        }
+        
+        return null;
+    }
+    
+    private Element getActualBody(Element root) {
+        NodeList list = root.getChildNodes();
+        for (int i = 0; i < list.getLength(); i++) {
+            Node node = list.item(i);
+            if (node instanceof Element) {
+                root.removeChild(node);
+                return (Element)node;
+            }
+        }
+        return null;
+       
+    }
+    
+    protected Element getNode(Element parent, String ns, String name) {
+        NodeList list = parent.getElementsByTagNameNS(ns, name);
+        if (list != null && list.getLength() == 1) {
+            return (Element)list.item(0);
+        } 
+        return null;
+    }
+}

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java?rev=1160689&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java
(added)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java
Tue Aug 23 13:47:51 2011
@@ -0,0 +1,104 @@
+/**
+ * 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.rs.security.saml;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.xml.AbstractXmlSecOutInterceptor;
+import org.apache.cxf.rs.security.xml.XmlEncOutInterceptor;
+import org.apache.cxf.rs.security.xml.XmlSigOutInterceptor;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+
+public class SamlEnvelopedOutInterceptor extends AbstractXmlSecOutInterceptor {
+
+    private static final String DEFAULT_ENV_NAME = "Envelope";
+    private static final String DEFAULT_ENV_NAMESPACE = "http://org.apache.cxf/rs/env";
+    private static final String DEFAULT_ENV_PREFIX = "env";
+    private String envelopeName = DEFAULT_ENV_NAME;
+    private String envelopeNamespace = DEFAULT_ENV_NAMESPACE;
+    private String envelopePrefix = DEFAULT_ENV_PREFIX;
+    
+    public SamlEnvelopedOutInterceptor() {
+        // SAML assertions may contain enveloped XML signatures so
+        // makes sense to avoid having them signed in the detached mode
+        super.addAfter(XmlSigOutInterceptor.class.getName());
+        
+        super.addBefore(XmlEncOutInterceptor.class.getName());
+    } 
+
+    
+    protected Document processDocument(Message message, Document doc) 
+        throws Exception {
+        return createEnvelopedSamlToken(message, doc);
+    }
+    
+    // enveloping & detached sigs will be supported too
+    private Document createEnvelopedSamlToken(Message message, Document payloadDoc) 
+        throws Exception {
+        
+        Document newDoc = DOMUtils.createDocument();
+        Element root = 
+            newDoc.createElementNS(envelopeNamespace, envelopePrefix + ":" + envelopeName);
+        newDoc.appendChild(root);
+        AssertionWrapper assertion = SAMLUtils.createAssertion(message);
+        Element assertionEl = assertion.toDOM(newDoc);
+        root.appendChild(assertionEl);
+        
+        Element docEl = payloadDoc.getDocumentElement();
+        payloadDoc.removeChild(docEl);
+        newDoc.adoptNode(docEl);
+        root.appendChild(docEl);
+        return newDoc;
+    }
+
+
+    public void setEnvelopeName(String envelopeName) {
+        this.envelopeName = envelopeName;
+    }
+
+
+    public String getEnvelopeName() {
+        return envelopeName;
+    }
+
+
+    public void setEnvelopeNamespace(String envelopeNamespace) {
+        this.envelopeNamespace = envelopeNamespace;
+    }
+
+
+    public String getEnvelopeNamespace() {
+        return envelopeNamespace;
+    }
+
+
+    public void setEnvelopePrefix(String envelopePrefix) {
+        this.envelopePrefix = envelopePrefix;
+    }
+
+
+    public String getEnvelopePrefix() {
+        return envelopePrefix;
+    }
+    
+}

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedOutInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlEncInHandler.java
Tue Aug 23 13:47:51 2011
@@ -24,7 +24,6 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
-import java.util.logging.Logger;
 
 import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
@@ -33,9 +32,7 @@ import javax.xml.stream.XMLStreamReader;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.Base64Exception;
 import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.helpers.DOMUtils;
@@ -46,7 +43,6 @@ import org.apache.cxf.rs.security.common
 import org.apache.cxf.staxutils.W3CDOMStreamReader;
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.util.WSSecurityUtil;
@@ -55,34 +51,16 @@ import org.apache.xml.security.encryptio
 import org.apache.xml.security.utils.Constants;
 
 
-public abstract class AbstractXmlEncInHandler {
-    private static final Logger LOG = 
-        LogUtils.getL7dLogger(AbstractXmlEncInHandler.class);
-    
-    static {
-        WSSConfig.init();
-    }
-    
+public abstract class AbstractXmlEncInHandler extends AbstractXmlSecInHandler {
     
     public void decryptContent(Message message) {
         Message outMs = message.getExchange().getOutMessage();
         Message inMsg = outMs == null ? message : outMs.getExchange().getInMessage();
-        String method = (String)inMsg.get(Message.HTTP_REQUEST_METHOD);
-        if ("GET".equals(method)) {
+        Document doc = getDocument(inMsg);
+        if (doc == null) {
             return;
         }
         
-        InputStream is = message.getContent(InputStream.class);
-        Document doc = null;
-        try {
-            doc = DOMUtils.readXml(is);
-        } catch (Exception ex) {
-            String errorMessage = "Invalid XML payload";
-            LOG.warning(errorMessage);
-            throwFault(errorMessage, ex);
-        }
-        
-
         Element root = doc.getDocumentElement();
         
         byte[] symmetricKeyBytes = getSymmetricKeyBytes(message, root);
@@ -233,15 +211,4 @@ public abstract class AbstractXmlEncInHa
     }
     
     
-    private Element getNode(Element parent, String ns, String name, int index) {
-        NodeList list = parent.getElementsByTagNameNS(ns, name);
-        if (list != null && list.getLength() >= index + 1) {
-            return (Element)list.item(index);
-        } 
-        return null;
-    }
-    
-       
-    protected abstract void throwFault(String error, Exception ex);
-    
 }

Added: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java?rev=1160689&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java
(added)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java
Tue Aug 23 13:47:51 2011
@@ -0,0 +1,94 @@
+/**
+ * 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.rs.security.xml;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.logging.Logger;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.xml.stream.XMLStreamReader;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.W3CDOMStreamReader;
+import org.apache.ws.security.WSSConfig;
+
+
+public abstract class AbstractXmlSecInHandler {
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(AbstractXmlSecInHandler.class);
+    
+    static {
+        WSSConfig.init();
+    }
+    
+    private boolean allowEmptyBody;
+    
+    public void setAllowEmptyBody(boolean allow) {
+        this.allowEmptyBody = allow;
+    }
+    
+    protected Document getDocument(Message message) {
+        String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
+        if ("GET".equals(method)) {
+            return null;
+        }
+        
+        Document doc = null;
+        InputStream is = message.getContent(InputStream.class);
+        if (is != null) {
+            try {
+                doc = DOMUtils.readXml(new InputStreamReader(is, "UTF-8"));
+            } catch (Exception ex) {
+                throwFault("Invalid XML payload", ex);
+            }
+        } else {
+            XMLStreamReader reader = message.getContent(XMLStreamReader.class);
+            if (reader instanceof W3CDOMStreamReader) {
+                doc = ((W3CDOMStreamReader)reader).getDocument();
+            }
+        }
+        if (doc == null && !allowEmptyBody) {
+            throwFault("No payload is available", null);
+        }
+        return doc;
+    }
+    
+    protected void throwFault(String error, Exception ex) {
+        LOG.warning(error);
+        Response response = Response.status(401).entity(error).build();
+        throw ex != null ? new WebApplicationException(ex, response) : new WebApplicationException(response);
+    }
+
+    protected Element getNode(Element parent, String ns, String name, int index) {
+        NodeList list = parent.getElementsByTagNameNS(ns, name);
+        if (list != null && list.getLength() >= index + 1) {
+            return (Element)list.item(index);
+        } 
+        return null;
+    }
+}

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecInHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecOutInterceptor.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecOutInterceptor.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSecOutInterceptor.java
Tue Aug 23 13:47:51 2011
@@ -61,8 +61,8 @@ public abstract class AbstractXmlSecOutI
             if (doc == null) {
                 return;
             }
- 
             Document finalDoc = processDocument(message, doc);
+            
             message.setContent(List.class, 
                 new MessageContentsList(new DOMSource(finalDoc)));
         } catch (Exception ex) {

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInHandler.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInHandler.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInHandler.java
Tue Aug 23 13:47:51 2011
@@ -19,20 +19,13 @@
 
 package org.apache.cxf.rs.security.xml;
 
-import java.util.logging.Logger;
-
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.jaxrs.ext.RequestHandler;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.message.Message;
 
 public class XmlEncInHandler extends AbstractXmlEncInHandler implements RequestHandler {
-    private static final Logger LOG = 
-        LogUtils.getL7dLogger(XmlEncInHandler.class);
-    
     
     public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
         
@@ -40,13 +33,4 @@ public class XmlEncInHandler extends Abs
         return null;
     }
     
-    protected void throwFault(String error, Exception ex) {
-        // TODO: get bundle resource message once this filter is moved 
-        // to rt/rs/security
-        LOG.warning(error);
-        Response response = Response.status(401).entity(error).build();
-        throw ex != null ? new WebApplicationException(ex, response) : new WebApplicationException(response);
-    }
-    
-    
 }

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInInterceptor.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInInterceptor.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncInInterceptor.java
Tue Aug 23 13:47:51 2011
@@ -21,12 +21,7 @@ package org.apache.cxf.rs.security.xml;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
-import java.util.logging.Logger;
 
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
-
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.Phase;
@@ -34,9 +29,6 @@ import org.apache.cxf.phase.PhaseInterce
 
 public class XmlEncInInterceptor extends AbstractXmlEncInHandler implements PhaseInterceptor<Message>
{
 
-    private static final Logger LOG = 
-        LogUtils.getL7dLogger(XmlEncInInterceptor.class);
-    
     public void handleFault(Message message) {
     }
 
@@ -44,12 +36,6 @@ public class XmlEncInInterceptor extends
         decryptContent(message);
     }
 
-    protected void throwFault(String error, Exception ex) {
-        LOG.warning(error);
-        Response response = Response.status(400).entity(error).build();
-        throw ex != null ? new WebApplicationException(ex, response) : new WebApplicationException(response);
-    }
-    
     public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors()
{
         return null;
     }

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java
Tue Aug 23 13:47:51 2011
@@ -22,9 +22,7 @@ package org.apache.cxf.rs.security.xml;
 import java.io.InputStream;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
-import java.util.logging.Logger;
 
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import javax.xml.stream.XMLStreamReader;
 
@@ -33,7 +31,6 @@ import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.jaxrs.ext.RequestHandler;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
@@ -42,7 +39,6 @@ import org.apache.cxf.rs.security.common
 import org.apache.cxf.rs.security.common.TrustValidator;
 import org.apache.cxf.staxutils.W3CDOMStreamReader;
 import org.apache.cxf.ws.security.SecurityConstants;
-import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.keys.KeyInfo;
@@ -52,37 +48,19 @@ import org.apache.xml.security.transform
 import org.apache.xml.security.transforms.Transforms;
 import org.apache.xml.security.utils.Constants;
 
-public class XmlSigInHandler implements RequestHandler {
-    private static final Logger LOG = 
-        LogUtils.getL7dLogger(XmlSigInHandler.class);
+public class XmlSigInHandler extends AbstractXmlSecInHandler implements RequestHandler {
     
-    static {
-        WSSConfig.init();
+    private boolean removeSignature = true;
+    
+    public void setRemoveSignature(boolean remove) {
+        this.removeSignature = remove;
     }
     
     public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
         
-        String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
-        if ("GET".equals(method)) {
-            return null;
-        }
-        
-        Document doc = null;
-        InputStream is = message.getContent(InputStream.class);
-        if (is != null) {
-            try {
-                doc = DOMUtils.readXml(is);
-            } catch (Exception ex) {
-                throwFault("Invalid XML payload", ex);
-            }
-        } else {
-            XMLStreamReader reader = message.getContent(XMLStreamReader.class);
-            if (reader instanceof W3CDOMStreamReader) {
-                doc = ((W3CDOMStreamReader)reader).getDocument();
-            }
-        }
+        Document doc = getDocument(message);
         if (doc == null) {
-            throwFault("No payload is available", null);
+            return null;
         }
 
         Element root = doc.getDocumentElement();
@@ -108,8 +86,7 @@ public class XmlSigInHandler implements 
         boolean valid = false;
         try {
             XMLSignature signature = new XMLSignature(sigElement, "");
-            // WSS4J SAMLUtil.getCredentialFromKeyInfo will also handle 
-            // the X509IssuerSerial case
+            // See also WSS4J SAMLUtil.getCredentialFromKeyInfo 
             KeyInfo keyInfo = signature.getKeyInfo();
             
             X509Certificate cert = keyInfo.getX509Certificate();
@@ -133,14 +110,16 @@ public class XmlSigInHandler implements 
         if (!valid) {
             throwFault("Signature validation failed", null);
         }
-        if (!isEnveloping(root)) {
-            root.removeAttribute("ID");
-            root.removeChild(sigElement);
-        } else {
-            Element actualBody = getActualBody(root);
-            Document newDoc = DOMUtils.createDocument();
-            newDoc.adoptNode(actualBody);
-            root = actualBody;
+        if (removeSignature) {
+            if (!isEnveloping(root)) {
+                root.removeAttribute("ID");
+                root.removeChild(sigElement);
+            } else {
+                Element actualBody = getActualBody(root);
+                Document newDoc = DOMUtils.createDocument();
+                newDoc.adoptNode(actualBody);
+                root = actualBody;
+            }
         }
         message.setContent(XMLStreamReader.class, 
                            new W3CDOMStreamReader(root));
@@ -184,21 +163,6 @@ public class XmlSigInHandler implements 
                 && "Signature".equals(root.getLocalName());
     }
     
-    private Element getNode(Element parent, String ns, String name, int index) {
-        NodeList list = parent.getElementsByTagNameNS(ns, name);
-        if (list != null && list.getLength() >= index + 1) {
-            return (Element)list.item(index);
-        } 
-        return null;
-    }
-    
-    protected void throwFault(String error, Exception ex) {
-        // TODO: get bundle resource message once this filter is moved 
-        // to rt/rs/security
-        LOG.warning(error);
-        Response response = Response.status(401).entity(error).build();
-        throw ex != null ? new WebApplicationException(ex, response) : new WebApplicationException(response);
-    }
     
     protected void validateReference(Element root, XMLSignature sig) {
         Reference ref = null;

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
(original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
Tue Aug 23 13:47:51 2011
@@ -35,6 +35,7 @@ import org.apache.cxf.jaxrs.client.WebCl
 import org.apache.cxf.jaxrs.ext.form.Form;
 import org.apache.cxf.jaxrs.provider.FormEncodingProvider;
 import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.saml.SamlEnvelopedOutInterceptor;
 import org.apache.cxf.rs.security.saml.SamlFormOutInterceptor;
 import org.apache.cxf.rs.security.saml.SamlHeaderOutInterceptor;
 import org.apache.cxf.systest.jaxrs.security.Book;
@@ -97,6 +98,28 @@ public class JAXRSSamlTest extends Abstr
         
     }
     
+    @Test
+    public void testEnvelopedSAMLToken() throws Exception {
+        String address = "https://localhost:" + PORT + "/samlxml/bookstore/books";
+        WebClient wc = createWebClient(address, new SamlEnvelopedOutInterceptor(),
+                                       null);
+        
+        wc.type(MediaType.APPLICATION_XML).accept(MediaType.APPLICATION_XML);
+        try {
+            Book book = wc.post(new Book("CXF", 125L), Book.class);                
+            assertEquals(125L, book.getId());
+        } catch (ServerWebApplicationException ex) {
+            fail(ex.getMessage());
+        } catch (ClientWebApplicationException ex) {
+            if (ex.getCause() != null && ex.getCause().getMessage() != null) {
+                fail(ex.getCause().getMessage());
+            } else {
+                fail(ex.getMessage());
+            }
+        }
+        
+    }
+    
     private WebClient createWebClient(String address, 
                                       Interceptor<Message> outInterceptor,
                                       Object provider) {

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/server.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/server.xml?rev=1160689&r1=1160688&r2=1160689&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/server.xml
(original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/server.xml
Tue Aug 23 13:47:51 2011
@@ -67,6 +67,7 @@ under the License.
     <bean id="serviceBean" class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
     <bean id="samlHeaderHandler" class="org.apache.cxf.rs.security.saml.SamlHeaderInHandler"/>
     <bean id="samlFormHandler" class="org.apache.cxf.rs.security.saml.SamlFormInHandler"/>
+    <bean id="samlEnvHandler" class="org.apache.cxf.rs.security.saml.SamlEnvelopedInHandler"/>
     
     <jaxrs:server 
        address="https://localhost:${testutil.ports.jaxrs-saml}/samlheader"> 
@@ -99,4 +100,20 @@ under the License.
        </jaxrs:properties>
         
     </jaxrs:server>
+    
+    <jaxrs:server 
+       address="https://localhost:${testutil.ports.jaxrs-saml}/samlxml"> 
+       <jaxrs:serviceBeans>
+          <ref bean="serviceBean"/>
+       </jaxrs:serviceBeans>
+       <jaxrs:providers>
+          <ref bean="samlEnvHandler"/>
+       </jaxrs:providers>
+       
+       <jaxrs:properties>
+           <entry key="ws-security.signature.properties" 
+                  value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
+       </jaxrs:properties>
+        
+    </jaxrs:server>
 </beans>



Mime
View raw message