CXF-7444 - Add the ability to configure custom SAML audience restriction values
# Conflicts: # rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java # rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java # rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java # rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/4c44d85a Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/4c44d85a Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/4c44d85a Branch: refs/heads/3.1.x-fixes Commit: 4c44d85a0fe2ebfe07269f71b54f603d4c2ec7a9 Parents: 3a5b6e3 Author: Colm O hEigeartaigh <[email protected]> Authored: Thu Jul 13 10:51:32 2017 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Thu Jul 13 12:37:21 2017 +0100 ---------------------------------------------------------------------- .../rs/security/saml/AbstractSamlInHandler.java | 19 +---- .../cxf/rt/security/saml/utils/SAMLUtils.java | 38 +++++++++- .../cxf/rt/security/SecurityConstants.java | 14 +++- .../ws/security/wss4j/WSS4JInInterceptor.java | 78 +++++++++++++++++++- .../security/wss4j/WSS4JStaxInInterceptor.java | 24 +----- .../cxf/systest/ws/saml/SamlTokenTest.java | 10 +++ .../cxf/systest/ws/saml/DoubleItSaml.wsdl | 3 + .../org/apache/cxf/systest/ws/saml/server.xml | 9 +++ .../apache/cxf/systest/ws/saml/stax-server.xml | 10 +++ 9 files changed, 160 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java index f8b3976..972be26 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java @@ -26,7 +26,6 @@ import java.nio.charset.StandardCharsets; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; -import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,6 +47,7 @@ import org.apache.cxf.rs.security.saml.authorization.SecurityContextProvider; import org.apache.cxf.rs.security.saml.authorization.SecurityContextProviderImpl; import org.apache.cxf.rs.security.xml.AbstractXmlSecInHandler; import org.apache.cxf.rt.security.SecurityConstants; +import org.apache.cxf.rt.security.saml.utils.SAMLUtils; import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.security.SecurityContext; import org.apache.cxf.security.transport.TLSSessionInfo; @@ -192,22 +192,7 @@ public abstract class AbstractSamlInHandler implements ContainerRequestFilter { } protected void configureAudienceRestriction(Message msg, RequestData reqData) { - // Add Audience Restrictions for SAML - boolean enableAudienceRestriction = false; - String audRestrStr = - (String)org.apache.cxf.rt.security.utils.SecurityUtils.getSecurityPropertyValue( - SecurityConstants.AUDIENCE_RESTRICTION_VALIDATION, msg); - if (audRestrStr != null) { - enableAudienceRestriction = Boolean.parseBoolean(audRestrStr); - } - - if (enableAudienceRestriction) { - List<String> audiences = new ArrayList<>(); - if (msg.getContextualProperty(org.apache.cxf.message.Message.REQUEST_URL) != null) { - audiences.add((String)msg.getContextualProperty(org.apache.cxf.message.Message.REQUEST_URL)); - } - reqData.setAudienceRestrictions(audiences); - } + reqData.setAudienceRestrictions(SAMLUtils.getAudienceRestrictions(msg)); } protected SAMLKeyInfo createKeyInfoFromDefaultAlias(Crypto sigCrypto) throws WSSecurityException { http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java ---------------------------------------------------------------------- diff --git a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java index f45a6de..a19c041 100644 --- a/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java +++ b/rt/security-saml/src/main/java/org/apache/cxf/rt/security/saml/utils/SAMLUtils.java @@ -20,15 +20,20 @@ package org.apache.cxf.rt.security.saml.utils; import java.net.URI; import java.security.Principal; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.w3c.dom.Element; import org.apache.cxf.common.security.SimpleGroup; +import org.apache.cxf.message.Message; +import org.apache.cxf.rt.security.SecurityConstants; import org.apache.cxf.rt.security.claims.Claim; import org.apache.cxf.rt.security.claims.ClaimCollection; import org.apache.cxf.rt.security.saml.claims.SAMLClaim; +import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.opensaml.core.xml.XMLObject; import org.opensaml.saml.common.SAMLVersion; @@ -137,5 +142,36 @@ public final class SAMLUtils { public static Element getAssertionElement(Object assertion) { return ((SamlAssertionWrapper)assertion).getElement(); } - + + public static List<String> getAudienceRestrictions(Message msg) { + // Add Audience Restrictions for SAML + boolean enableAudienceRestriction = + SecurityUtils.getSecurityPropertyBoolean(SecurityConstants.AUDIENCE_RESTRICTION_VALIDATION, msg, true); + if (enableAudienceRestriction) { + List<String> audiences = new ArrayList<>(); + // See if we have custom audience restriction values specified first + String audienceRestrictions = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.AUDIENCE_RESTRICTIONS, msg); + if (audienceRestrictions != null) { + for (String audienceRestriction : audienceRestrictions.split(",")) { + audiences.add(audienceRestriction); + } + } + + // Defaults + if (audiences.isEmpty()) { + if (msg.get(org.apache.cxf.message.Message.REQUEST_URL) != null) { + audiences.add((String)msg.get(org.apache.cxf.message.Message.REQUEST_URL)); + } else if (msg.get(org.apache.cxf.message.Message.REQUEST_URI) != null) { + audiences.add((String)msg.get(org.apache.cxf.message.Message.REQUEST_URI)); + } + + if (msg.getContextualProperty("javax.xml.ws.wsdl.service") != null) { + audiences.add(msg.getContextualProperty("javax.xml.ws.wsdl.service").toString()); + } + } + return audiences; + } + return Collections.emptyList(); + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java ---------------------------------------------------------------------- diff --git a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java index 61d3966..c285510 100644 --- a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java +++ b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java @@ -180,8 +180,8 @@ public class SecurityConstants { /** * Enable SAML AudienceRestriction validation. If this is set to "true", then IF the - * SAML Token contains Audience Restriction URIs, one of them must match either the - * request URL or the Service QName. The default is "true". + * SAML Token contains Audience Restriction URIs, one of them must match one of the values of the + * AUDIENCE_RESTRICTIONS property. The default is "true". */ public static final String AUDIENCE_RESTRICTION_VALIDATION = "security.validate.audience-restriction"; @@ -351,6 +351,14 @@ public class SecurityConstants { public static final String STS_TOKEN_CACHER_IMPL = "security.sts.token.cacher.impl"; + /** + * This property contains a comma separated String corresponding to a list of audience restriction URIs. + * The default value for this property contains the request URL and the Service QName. If the + * AUDIENCE_RESTRICTION_VALIDATION property is "true", and if a received SAML Token contains audience + * restriction URIs, then one of them must match one of the values specified in this property. + */ + public static final String AUDIENCE_RESTRICTIONS = "security.audience-restrictions"; + public static final Set<String> COMMON_PROPERTIES; static { @@ -366,7 +374,7 @@ public class SecurityConstants { DISABLE_STS_CLIENT_WSMEX_CALL_USING_EPR_ADDRESS, STS_TOKEN_CRYPTO, STS_TOKEN_PROPERTIES, STS_TOKEN_USERNAME, STS_TOKEN_ACT_AS, STS_TOKEN_ON_BEHALF_OF, STS_CLIENT, STS_APPLIES_TO, CACHE_ISSUED_TOKEN_IN_ENDPOINT, PREFER_WSMEX_OVER_STS_CLIENT_CONFIG, - STS_TOKEN_IMMINENT_EXPIRY_VALUE, STS_TOKEN_CACHER_IMPL + STS_TOKEN_IMMINENT_EXPIRY_VALUE, STS_TOKEN_CACHER_IMPL, AUDIENCE_RESTRICTIONS })); COMMON_PROPERTIES = Collections.unmodifiableSet(s); } http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java index fde6e8c..81f6a76 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java @@ -52,6 +52,7 @@ import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.MessageUtils; import org.apache.cxf.phase.Phase; +import org.apache.cxf.rt.security.saml.utils.SAMLUtils; import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.security.transport.TLSSessionInfo; import org.apache.cxf.staxutils.StaxUtils; @@ -199,8 +200,8 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor { reqData.setEncryptionSerializer(new StaxSerializer()); // Add Audience Restrictions for SAML - configureAudienceRestriction(msg, reqData); - + reqData.setAudienceRestrictions(SAMLUtils.getAudienceRestrictions(msg)); + SOAPMessage doc = getSOAPMessage(msg); boolean doDebug = LOG.isLoggable(Level.FINE); @@ -330,6 +331,7 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor { reqData = null; } } +<<<<<<< HEAD private void configureAudienceRestriction(SoapMessage msg, RequestData reqData) { // Add Audience Restrictions for SAML @@ -350,6 +352,78 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor { } } +======= + private void importNewDomToSAAJ(SOAPMessage doc, Element elem, + Node originalNode, WSHandlerResult wsResult) throws SOAPException { + if (DOMUtils.isJava9SAAJ() + && originalNode != null && !originalNode.isEqualNode(elem)) { + //ensure the new decrypted dom element could be imported into the SAAJ + Node node = null; + Document document = null; + Element body = SAAJUtils.getBody(doc); + if (body != null) { + document = body.getOwnerDocument(); + } + if (elem != null && elem.getOwnerDocument() != null + && elem.getOwnerDocument().getDocumentElement() != null) { + node = elem.getOwnerDocument(). + getDocumentElement().getFirstChild().getNextSibling().getFirstChild(); + } + if (document != null && node != null) { + Node newNode = null; + try { + newNode = document.importNode(node, true); + if (newNode != null) { + try { + Method method = newNode.getClass().getMethod("getDomElement"); + newNode = (Element)method.invoke(newNode); + } catch (java.lang.NoSuchMethodException ex) { + // do nothing; + } + } + elem.getOwnerDocument().getDocumentElement().getFirstChild(). + getNextSibling().replaceChild(newNode, node); + List<WSSecurityEngineResult> encryptResults = wsResult.getActionResults().get(WSConstants.ENCR); + if (encryptResults != null) { + for (WSSecurityEngineResult result : wsResult.getActionResults().get(WSConstants.ENCR)) { + for (WSDataRef dataRef + : (List<WSDataRef>)result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS)) { + if (dataRef.getProtectedElement() == node) { + dataRef.setProtectedElement((Element)newNode); + } + } + } + } + + List<WSSecurityEngineResult> signedResults = new ArrayList<>(); + if (wsResult.getActionResults().containsKey(WSConstants.SIGN)) { + signedResults.addAll(wsResult.getActionResults().get(WSConstants.SIGN)); + } + if (wsResult.getActionResults().containsKey(WSConstants.UT_SIGN)) { + signedResults.addAll(wsResult.getActionResults().get(WSConstants.UT_SIGN)); + } + if (wsResult.getActionResults().containsKey(WSConstants.ST_SIGNED)) { + signedResults.addAll(wsResult.getActionResults().get(WSConstants.ST_SIGNED)); + } + for (WSSecurityEngineResult result : signedResults) { + for (WSDataRef dataRef + : (List<WSDataRef>)result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS)) { + if (dataRef.getProtectedElement() == node) { + dataRef.setProtectedElement((Element)newNode); + } + } + } + } catch (Exception ex) { + //just to the best try + LOG.log(Level.FINE, "Something wrong during importNewDomToSAAJ", ex); + } + + } + + } + } + +>>>>>>> 3779d24229... CXF-7444 - Add the ability to configure custom SAML audience restriction values private void checkActions( SoapMessage msg, RequestData reqData, http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java index a4ed602..917217e 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java @@ -19,7 +19,6 @@ package org.apache.cxf.ws.security.wss4j; import java.security.Provider; -import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -41,6 +40,7 @@ import org.apache.cxf.interceptor.Fault; import org.apache.cxf.interceptor.StaxInInterceptor; import org.apache.cxf.message.MessageUtils; import org.apache.cxf.phase.Phase; +import org.apache.cxf.rt.security.saml.utils.SAMLUtils; import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.ws.security.SecurityConstants; import org.apache.cxf.ws.security.tokenstore.TokenStoreUtils; @@ -293,27 +293,7 @@ public class WSS4JStaxInInterceptor extends AbstractWSS4JStaxInterceptor { } // Add Audience Restrictions for SAML - configureAudienceRestriction(msg, securityProperties); - } - - private void configureAudienceRestriction(SoapMessage msg, WSSSecurityProperties securityProperties) { - // Add Audience Restrictions for SAML - boolean enableAudienceRestriction = true; - String audRestrStr = - (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.AUDIENCE_RESTRICTION_VALIDATION, msg); - if (audRestrStr != null) { - enableAudienceRestriction = Boolean.parseBoolean(audRestrStr); - } - if (enableAudienceRestriction) { - List<String> audiences = new ArrayList<String>(); - if (msg.getContextualProperty(org.apache.cxf.message.Message.REQUEST_URL) != null) { - audiences.add((String)msg.getContextualProperty(org.apache.cxf.message.Message.REQUEST_URL)); - } - if (msg.getContextualProperty("javax.xml.ws.wsdl.service") != null) { - audiences.add(msg.getContextualProperty("javax.xml.ws.wsdl.service").toString()); - } - securityProperties.setAudienceRestrictions(audiences); - } + securityProperties.setAudienceRestrictions(SAMLUtils.getAudienceRestrictions(msg)); } /** http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/SamlTokenTest.java ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/SamlTokenTest.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/SamlTokenTest.java index 64219eb..bab46c7 100644 --- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/SamlTokenTest.java +++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/SamlTokenTest.java @@ -1152,6 +1152,16 @@ public class SamlTokenTest extends AbstractBusClientServerTestBase { SecurityConstants.SAML_CALLBACK_HANDLER, callbackHandler ); saml2Port.doubleIt(25); + + // It should pass because we explicitly allow the given audience restriction + portQName = new QName(NAMESPACE, "DoubleItSaml2TransportPort4"); + saml2Port = service.getPort(portQName, DoubleItPortType.class); + updateAddressPort(saml2Port, portNumber); + + ((BindingProvider)saml2Port).getRequestContext().put( + SecurityConstants.SAML_CALLBACK_HANDLER, callbackHandler + ); + saml2Port.doubleIt(25); } @org.junit.Test http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl index ea0d132..099d828 100644 --- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl @@ -386,6 +386,9 @@ <wsdl:port name="DoubleItSaml2TransportPort3" binding="tns:DoubleItSaml2TransportBinding"> <soap:address location="https://localhost:9009/DoubleItSaml2Transport3"/> </wsdl:port> + <wsdl:port name="DoubleItSaml2TransportPort4" binding="tns:DoubleItSaml2TransportBinding"> + <soap:address location="https://localhost:9009/DoubleItSaml2Transport4"/> + </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItSaml1TransportPolicy"> <wsp:ExactlyOne> http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server.xml index 30d3218..e9f7e3e 100644 --- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server.xml +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/server.xml @@ -267,4 +267,13 @@ <entry key="security.validate.audience-restriction" value="false"/> </jaxws:properties> </jaxws:endpoint> + + <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="Saml2TransportToken4" address="https://localhost:${testutil.ports.saml.Server.2}/DoubleItSaml2Transport4" serviceName="s:DoubleItService" endpointName="s:DoubleItSaml2TransportPort4" implementor="org.apache.cxf.systest.ws.common.DoubleItPortTypeImpl" wsdlLocation="org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl" depends-on="tls-settings"> + <jaxws:properties> + <entry key="security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/> + <entry key="security.signature.properties" value="bob.properties"/> + <entry key="security.subject.cert.constraints" value=".*O=apache.org.*"/> + <entry key="security.audience-restrictions" value="{http://www.example.org/contract/DoubleIt}DoubleItService,{http://www.example.org/contract/DoubleIt}DoubleItService.xyz"/> + </jaxws:properties> + </jaxws:endpoint> </beans> http://git-wip-us.apache.org/repos/asf/cxf/blob/4c44d85a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/stax-server.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/stax-server.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/stax-server.xml index fb0a222..6ad448c 100644 --- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/stax-server.xml +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/saml/stax-server.xml @@ -295,4 +295,14 @@ <entry key="security.validate.audience-restriction" value="false"/> </jaxws:properties> </jaxws:endpoint> + + <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="Saml2TransportToken4" address="https://localhost:${testutil.ports.saml.StaxServer.2}/DoubleItSaml2Transport4" serviceName="s:DoubleItService" endpointName="s:DoubleItSaml2TransportPort4" implementor="org.apache.cxf.systest.ws.common.DoubleItPortTypeImpl" wsdlLocation="org/apache/cxf/systest/ws/saml/DoubleItSaml.wsdl" depends-on="tls-settings"> + <jaxws:properties> + <entry key="security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/> + <entry key="security.signature.properties" value="bob.properties"/> + <entry key="security.subject.cert.constraints" value=".*O=apache.org.*"/> + <entry key="ws-security.enable.streaming" value="true"/> + <entry key="security.audience-restrictions" value="{http://www.example.org/contract/DoubleIt}DoubleItService,{http://www.example.org/contract/DoubleIt}DoubleItService.xyz"/> + </jaxws:properties> + </jaxws:endpoint> </beans>
