Author: dkulp Date: Fri Jul 13 18:42:35 2012 New Revision: 1361331 URL: http://svn.apache.org/viewvc?rev=1361331&view=rev Log: Merged revisions 1361328 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/branches/2.6.x-fixes
........ r1361328 | dkulp | 2012-07-13 14:39:25 -0400 (Fri, 13 Jul 2012) | 11 lines Merged revisions 1361325 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/trunk ........ r1361325 | dkulp | 2012-07-13 14:36:09 -0400 (Fri, 13 Jul 2012) | 3 lines Work around JAXB-909 which is preventing various SAML assertions from validating in the STS. ........ ........ Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/sts/provider/SecurityTokenServiceProvider.java Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/sts/provider/SecurityTokenServiceProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/sts/provider/SecurityTokenServiceProvider.java?rev=1361331&r1=1361330&r2=1361331&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/sts/provider/SecurityTokenServiceProvider.java (original) +++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/sts/provider/SecurityTokenServiceProvider.java Fri Jul 13 18:42:35 2012 @@ -19,6 +19,7 @@ package org.apache.cxf.ws.security.sts.provider; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; @@ -28,9 +29,10 @@ import java.util.Map; import java.util.Set; import javax.annotation.Resource; +import javax.xml.bind.Binder; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; -import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.util.JAXBSource; import javax.xml.namespace.QName; import javax.xml.transform.Source; @@ -40,10 +42,17 @@ import javax.xml.ws.ServiceMode; import javax.xml.ws.WebServiceContext; import javax.xml.ws.handler.MessageContext; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + import org.apache.cxf.binding.soap.SoapFault; import org.apache.cxf.binding.soap.SoapVersion; import org.apache.cxf.jaxb.JAXBContextCache; import org.apache.cxf.jaxb.JAXBContextCache.CachedContextAndSchemas; +import org.apache.cxf.common.util.ReflectionUtil; +import org.apache.cxf.helpers.DOMUtils; +import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.ws.security.sts.provider.model.ObjectFactory; import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenCollectionType; import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseCollectionType; @@ -278,12 +287,56 @@ public class SecurityTokenServiceProvide } private Object convertToJAXBObject(Source source) throws Exception { - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - JAXBElement<?> jaxbElement = (JAXBElement<?>) unmarshaller - .unmarshal(source); + //this is entirely to work around http://java.net/jira/browse/JAXB-909 + //if that bug is ever fixed and we can detect it, we can remove this + //complete and total HACK HACK HACK and replace with just: + //Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + //JAXBElement<?> jaxbElement = (JAXBElement<?>) unmarshaller.unmarshal(source); + //return jaxbElement.getValue(); + + Document d = StaxUtils.read(source); + Binder<Node> binder = jaxbContext.createBinder(); + JAXBElement<?> jaxbElement = (JAXBElement<?>)binder.unmarshal(d); + walkDom("", d.getDocumentElement(), binder, null); return jaxbElement.getValue(); } + private void walkDom(String pfx, Element element, Binder<Node> binder, Object parent) { + try { + Object o = binder.getJAXBNode(element); + if (o instanceof JAXBElement) { + o = ((JAXBElement<?>)o).getValue(); + } + //System.out.println(pfx + DOMUtils.getElementQName(element) + " -> " + // + (o == null ? "null" : o.getClass())); + if (o == null && parent != null) { + // if it's not able to bind to an object, it's possibly an xsd:any + // we'll check the parent for the standard "any" and replace with + // the original element. + Field f = parent.getClass().getDeclaredField("any"); + if (f.getAnnotation(XmlAnyElement.class) != null) { + Object old = ReflectionUtil.setAccessible(f).get(parent); + if (old instanceof Element + && DOMUtils.getElementQName(element).equals(DOMUtils.getElementQName((Element)old))) { + ReflectionUtil.setAccessible(f).set(parent, element); + } + } + } + if (o == null) { + return; + } + Node nd = element.getFirstChild(); + while (nd != null) { + if (nd instanceof Element) { + walkDom(pfx + " ", (Element)nd, binder, o); + } + nd = nd.getNextSibling(); + } + } catch (Throwable t) { + //ignore -this is a complete hack anyway + } + } + public CancelOperation getCancelOperation() { return cancelOperation; }
