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>