You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2011/08/30 02:12:37 UTC

svn commit: r1163060 - in /cxf/trunk/rt/ws: addr/src/main/java/org/apache/cxf/ws/addressing/ addr/src/main/java/org/apache/cxf/ws/addressing/soap/ security/ security/src/main/java/org/apache/cxf/ws/security/policy/builders/ security/src/main/java/org/a...

Author: dkulp
Date: Tue Aug 30 00:12:36 2011
New Revision: 1163060

URL: http://svn.apache.org/viewvc?rev=1163060&view=rev
Log:
[CXF-3394] More work toward WS-MEX
IssuedTokens can now use Issuer elements in the IssuedToken to configure
the STS.  MEX calls are made to the STS to get the WSDL/Policies.

Modified:
    cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/VersionTransformer.java
    cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
    cxf/trunk/rt/ws/security/pom.xml
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/IssuedTokenBuilder.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/IssuedToken.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSUtils.java

Modified: cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/VersionTransformer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/VersionTransformer.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/VersionTransformer.java (original)
+++ cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/VersionTransformer.java Tue Aug 30 00:12:36 2011
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.namespace.QName;
 import javax.xml.parsers.ParserConfigurationException;
@@ -32,6 +33,9 @@ import javax.xml.ws.EndpointReference;
 import javax.xml.ws.wsaddressing.W3CEndpointReference;
 
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.ibm.wsdl.util.xml.DOMUtils;
 
 // importation convention: if the same class name is used for 
 // 2005/08 and 2004/08, then the former version is imported
@@ -74,7 +78,7 @@ public class VersionTransformer {
     /**
      * Constructor.
      */
-    public VersionTransformer() {
+    protected VersionTransformer() {
     }
     
     /**
@@ -82,7 +86,7 @@ public class VersionTransformer {
      * @return true if th WS-Addressing version specified by the namespace 
      * URI is supported
      */
-    public boolean isSupported(String namespace) {
+    public static boolean isSupported(String namespace) {
         return NATIVE_VERSION.equals(namespace) 
                || Names200408.WSA_NAMESPACE_NAME.equals(namespace)
                || Names200403.WSA_NAMESPACE_NAME.equals(namespace);
@@ -457,8 +461,66 @@ public class VersionTransformer {
         }
         return internal;
     }
+    
+    
+    /**
+     * Parse an EndpointReferenceType from a DOM element.  Handles all of
+     * the WS-Addressing namespaces currently supported.
+     * @param ref
+     * @return
+     * @throws JAXBException
+     */
+    public static EndpointReferenceType parseEndpointReference(Element ref) throws JAXBException {
+        Element child = DOMUtils.getFirstChildElement(ref);
+        String tns = null;
+        while (child != null && tns == null) {
+            if (isSupported(child.getNamespaceURI())) {
+                tns = child.getNamespaceURI();
+            }
+            child = DOMUtils.getNextSiblingElement(child);
+        }
+        if (tns == null) {
+            return null;
+        }
+        JAXBContext ctx = getExposedJAXBContext(tns);
+        Object o = ctx.createUnmarshaller().unmarshal(ref, getExposedReferenceType(tns));
+        if (o instanceof JAXBElement) {
+            o = ((JAXBElement)o).getValue();
+        }
+        return convertToNative(o);
+        
+    }
+    /**
+     * Converts a version specific EndpointReferenceType to the native version
+     * used internally by CXF
+     * @param exposed
+     * @return
+     */
+    public static EndpointReferenceType convertToNative(Object exposed) {
+        if (EndpointReferenceType.class.isInstance(exposed)) {
+            return (EndpointReferenceType)exposed;
+        } else if (Names200408.EPR_TYPE.isInstance(exposed)) {
+            return convert((org.apache.cxf.ws.addressing.v200408.EndpointReferenceType)exposed);
+        } else if (Names200403.EPR_TYPE.isInstance(exposed)) {
+            return convert((org.apache.cxf.ws.addressing.v200403.EndpointReferenceType)exposed);
+        }        
+        return null;
+    }
 
     /**
+     * Gets the Class representing the EndpointReferenceType that is used
+     * for the specific WS-Addressing version
+     * @param exposedURI
+     * @return
+     */
+    public static Class<?> getExposedReferenceType(String exposedURI) {
+        return NATIVE_VERSION.equals(exposedURI)
+            ? EndpointReferenceType.class 
+                : Names200408.WSA_NAMESPACE_NAME.equals(exposedURI) ? Names200408.EPR_TYPE 
+                    : Names200403.WSA_NAMESPACE_NAME.equals(exposedURI) ? Names200403.EPR_TYPE : null;
+    }
+    
+    /**
      * @param exposedURI specifies the version WS-Addressing
      * @return JABXContext for the exposed namespace URI
      */

Modified: cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java (original)
+++ cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java Tue Aug 30 00:12:36 2011
@@ -506,7 +506,7 @@ public class MAPCodec extends AbstractSo
                         // Need to check the uri before getting unmarshaller else
                         // would get wrong unmarshaller and fail to process required
                         // headers.
-                        if (transformer.isSupported(headerURI)) {
+                        if (VersionTransformer.isSupported(headerURI)) {
                             if (unmarshaller == null) {
                                 JAXBContext jaxbContext = 
                                     VersionTransformer.getExposedJAXBContext(headerURI);

Modified: cxf/trunk/rt/ws/security/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/pom.xml?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/pom.xml (original)
+++ cxf/trunk/rt/ws/security/pom.xml Tue Aug 30 00:12:36 2011
@@ -67,6 +67,12 @@
         </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-ws-mex</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-rt-transports-http</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/IssuedTokenBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/IssuedTokenBuilder.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/IssuedTokenBuilder.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/IssuedTokenBuilder.java Tue Aug 30 00:12:36 2011
@@ -21,11 +21,14 @@ package org.apache.cxf.ws.security.polic
 import java.util.Iterator;
 import java.util.List;
 
+import javax.xml.bind.JAXBException;
 import javax.xml.namespace.QName;
 
 import org.w3c.dom.Element;
 
 import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.apache.cxf.ws.addressing.VersionTransformer;
 import org.apache.cxf.ws.policy.PolicyBuilder;
 import org.apache.cxf.ws.policy.PolicyConstants;
 import org.apache.cxf.ws.security.policy.SP11Constants;
@@ -39,8 +42,6 @@ import org.apache.neethi.builders.Assert
 
 
 public class IssuedTokenBuilder implements AssertionBuilder<Element> {
-    private static final String WSA_NAMESPACE_SUB = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
-    private static final String WSA_NAMESPACE = "http://www.w3.org/2005/08/addressing";
     
     PolicyBuilder builder;
     public IssuedTokenBuilder(PolicyBuilder b) {
@@ -69,33 +70,13 @@ public class IssuedTokenBuilder implemen
         Element child = DOMUtils.getFirstElement(element);
         while (child != null) {
             String ln = child.getLocalName();
-            if (SP11Constants.ISSUER.getLocalPart().equals(ln)) {
-                Element issuerEpr = DOMUtils
-                    .getFirstChildWithName(child, 
-                                       new QName(WSA_NAMESPACE, "Address"));
-
-                // try the other addressing namespace
-                if (issuerEpr == null) {
-                    issuerEpr = DOMUtils
-                        .getFirstChildWithName(child,
-                                           new QName(WSA_NAMESPACE_SUB,
-                                                     "Address"));
+            if (SPConstants.ISSUER.equals(ln)) {
+                try {
+                    EndpointReferenceType epr = VersionTransformer.parseEndpointReference(child);
+                    issuedToken.setIssuerEpr(epr);
+                } catch (JAXBException e) {
+                    throw new IllegalArgumentException(e);
                 }
-                issuedToken.setIssuerEpr(issuerEpr);
-
-                Element issuerMex = DOMUtils
-                    .getFirstChildWithName(child,
-                                       new QName(WSA_NAMESPACE, "Metadata"));
-
-                // try the other addressing namespace
-                if (issuerMex == null) {
-                    issuerMex = DOMUtils
-                        .getFirstChildWithName(child,
-                                               new QName(WSA_NAMESPACE_SUB, 
-                                                         "Metadata"));
-                }
-    
-                issuedToken.setIssuerMex(issuerMex);
             } else if (SPConstants.REQUEST_SECURITY_TOKEN_TEMPLATE.equals(ln)) {
                 issuedToken.setRstTemplate(child);
             } else if (org.apache.neethi.Constants.ELEM_POLICY.equals(ln)) {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java Tue Aug 30 00:12:36 2011
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.CastUtils;
@@ -94,6 +95,17 @@ public class IssuedTokenInterceptorProvi
     static class IssuedTokenOutInterceptor extends AbstractPhaseInterceptor<Message> {
         public IssuedTokenOutInterceptor() {
             super(Phase.PREPARE_SEND);
+        }    
+        private static void mapSecurityProps(Message message, Map<String, Object> ctx) {
+            for (String s : SecurityConstants.ALL_PROPERTIES) {
+                Object v = message.getContextualProperty(s + ".it");
+                if (v == null) {
+                    v = message.getContextualProperty(s);
+                }
+                if (v != null) {
+                    ctx.put(s, v);
+                }
+            }
         }
         public void handleMessage(Message message) throws Fault {
             AssertionInfoMap aim = message.get(AssertionInfoMap.class);
@@ -114,7 +126,7 @@ public class IssuedTokenInterceptorProvi
                         }
                     }
                     if (tok == null) {
-                        STSClient client = STSUtils.getClient(message, "sts");
+                        STSClient client = STSUtils.getClient(message, "sts", itok);
                         AddressingProperties maps =
                             (AddressingProperties)message
                                 .get("javax.xml.ws.addressing.context.outbound");
@@ -135,7 +147,9 @@ public class IssuedTokenInterceptorProvi
                                 if (token != null) {
                                     client.setOnBehalfOf(token);
                                 }
-
+                                Map<String, Object> ctx = client.getRequestContext();
+                                mapSecurityProps(message, ctx);
+                            
                                 client.setMessage(message);
                                 client.setTrust(getTrust10(aim));
                                 client.setTrust(getTrust13(aim));

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/IssuedToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/IssuedToken.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/IssuedToken.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/IssuedToken.java Tue Aug 30 00:12:36 2011
@@ -18,6 +18,8 @@
  */
 package org.apache.cxf.ws.security.policy.model;
 
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
@@ -25,6 +27,8 @@ import javax.xml.stream.XMLStreamWriter;
 import org.w3c.dom.Element;
 
 import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.ws.addressing.ContextUtils;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
 import org.apache.cxf.ws.security.policy.SP12Constants;
 import org.apache.cxf.ws.security.policy.SPConstants;
 
@@ -33,9 +37,7 @@ import org.apache.cxf.ws.security.policy
  */
 public class IssuedToken extends Token {
 
-    private Element issuerEpr;
-
-    private Element issuerMex;
+    private EndpointReferenceType issuerEpr;
 
     private Element rstTemplate;
 
@@ -50,14 +52,14 @@ public class IssuedToken extends Token {
     /**
      * @return Returns the issuerEpr.
      */
-    public Element getIssuerEpr() {
+    public EndpointReferenceType getIssuerEpr() {
         return issuerEpr;
     }
 
     /**
      * @param issuerEpr The issuerEpr to set.
      */
-    public void setIssuerEpr(Element issuerEpr) {
+    public void setIssuerEpr(EndpointReferenceType issuerEpr) {
         this.issuerEpr = issuerEpr;
     }
 
@@ -141,9 +143,14 @@ public class IssuedToken extends Token {
         }
 
         if (issuerEpr != null) {
-            writer.writeStartElement(prefix, SPConstants.ISSUER, namespaceURI);
-            StaxUtils.copy(issuerEpr, writer);
-            writer.writeEndElement();
+            JAXBElement<EndpointReferenceType> elem 
+                = new JAXBElement<EndpointReferenceType>(new QName(namespaceURI, SPConstants.ISSUER), 
+                    EndpointReferenceType.class, issuerEpr);
+            try {
+                ContextUtils.getJAXBContext().createMarshaller().marshal(elem, writer);
+            } catch (JAXBException e) {
+                //ignore
+            }
         }
 
         if (rstTemplate != null) {
@@ -198,12 +205,5 @@ public class IssuedToken extends Token {
         writer.writeEndElement();
     }
 
-    public Element getIssuerMex() {
-        return issuerMex;
-    }
-
-    public void setIssuerMex(Element issuerMex) {
-        this.issuerMex = issuerMex;
-    }
 
 }

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java Tue Aug 30 00:12:36 2011
@@ -37,6 +37,7 @@ import java.util.logging.Logger;
 
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
+import javax.wsdl.Definition;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
@@ -69,6 +70,7 @@ import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.interceptor.InterceptorProvider;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.resource.ResourceManager;
 import org.apache.cxf.service.Service;
@@ -76,9 +78,15 @@ import org.apache.cxf.service.model.Bind
 import org.apache.cxf.service.model.BindingOperationInfo;
 import org.apache.cxf.service.model.EndpointInfo;
 import org.apache.cxf.service.model.MessagePartInfo;
+import org.apache.cxf.service.model.ServiceInfo;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.staxutils.W3CDOMStreamWriter;
 import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.apache.cxf.ws.addressing.VersionTransformer;
+import org.apache.cxf.ws.mex.MetadataExchange;
+import org.apache.cxf.ws.mex.model._2004_09.Metadata;
+import org.apache.cxf.ws.mex.model._2004_09.MetadataSection;
 import org.apache.cxf.ws.policy.EffectivePolicy;
 import org.apache.cxf.ws.policy.PolicyBuilder;
 import org.apache.cxf.ws.policy.PolicyConstants;
@@ -96,6 +104,8 @@ import org.apache.cxf.ws.security.policy
 import org.apache.cxf.ws.security.policy.model.Trust13;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.cxf.ws.security.trust.delegation.DelegationCallback;
+import org.apache.cxf.wsdl.EndpointReferenceUtils;
+import org.apache.cxf.wsdl.WSDLManager;
 import org.apache.cxf.wsdl11.WSDLServiceFactory;
 import org.apache.neethi.All;
 import org.apache.neethi.ExactlyOne;
@@ -405,7 +415,80 @@ public class STSClient implements Config
         }
         return client;
     }
-
+    
+    public void configureViaEPR(EndpointReferenceType ref) {
+        if (client != null) {
+            return;
+        }
+        location = EndpointReferenceUtils.getAddress(ref);
+        String mexLoc = findMEXLocation(ref);
+        if (mexLoc != null) {
+            try {
+                JaxWsProxyFactoryBean proxyFac = new JaxWsProxyFactoryBean();
+                proxyFac.setAddress(mexLoc);
+                MetadataExchange exc = proxyFac.create(MetadataExchange.class);
+                Metadata metadata = exc.get2004();
+                for (MetadataSection s : metadata.getMetadataSection()) {
+                    if ("http://schemas.xmlsoap.org/wsdl/".equals(s.getDialect())) {
+                        //got the wsdl...
+                        Definition definition = bus.getExtension(WSDLManager.class)
+                            .getDefinition((Element)s.getAny());
+                        WSDLServiceFactory factory = new WSDLServiceFactory(bus, definition);
+                        SourceDataBinding dataBinding = new SourceDataBinding();
+                        factory.setDataBinding(dataBinding);
+                        Service service = factory.create();
+                        service.setDataBinding(dataBinding);
+                        
+                        
+                        for (ServiceInfo serv : service.getServiceInfos()) {
+                            for (EndpointInfo ei : serv.getEndpoints()) {
+                                if (ei.getAddress().equals(location)) {
+                                    endpointName = ei.getName();
+                                    serviceName = serv.getName();
+                                }
+                            }
+                        }
+                        EndpointInfo ei = service.getEndpointInfo(endpointName);
+                        Endpoint endpoint = new EndpointImpl(bus, service, ei);
+                        client = new ClientImpl(bus, endpoint);
+                    }
+                }
+            } catch (Exception ex) {
+                //TODO
+                ex.printStackTrace();
+            }
+        }
+    }
+    private String findMEXLocation(EndpointReferenceType ref) {
+        if (ref.getMetadata() != null && ref.getMetadata().getAny() != null) {
+            for (Object any : ref.getMetadata().getAny()) {
+                if (any instanceof Element) {
+                    String addr = findMEXLocation((Element)any);
+                    if (addr != null) {
+                        return addr;
+                    }
+                }
+            }
+        }
+        return EndpointReferenceUtils.getAddress(ref);
+    }
+    private String findMEXLocation(Element ref) {
+        Element el = DOMUtils.getFirstElement(ref);
+        while (el != null) {
+            if (el.getLocalName().equals("Address")
+                && VersionTransformer.isSupported(el.getNamespaceURI())
+                && "MetadataReference".equals(ref.getLocalName())) {
+                return DOMUtils.getContent(el);
+            } else {
+                String ad = findMEXLocation(el);
+                if (ad != null) {
+                    return ad;
+                }
+            }
+            el = DOMUtils.getNextElement(el);
+        }
+        return null;
+    }
     private void createClient() throws BusException, EndpointException {
         if (client != null) {
             return;

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSUtils.java?rev=1163060&r1=1163059&r2=1163060&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSUtils.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSUtils.java Tue Aug 30 00:12:36 2011
@@ -44,6 +44,7 @@ import org.apache.cxf.service.model.Serv
 import org.apache.cxf.transport.ConduitInitiator;
 import org.apache.cxf.transport.ConduitInitiatorManager;
 import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.policy.model.IssuedToken;
 import org.apache.neethi.Policy;
 
 /**
@@ -81,18 +82,38 @@ public final class STSUtils {
     }
     
     public static STSClient getClient(Message message, String type) {
-        if (type == null) {
-            type = "";
-        } else {
-            type = "." + type + "-client";
+        STSClient client = (STSClient)message
+            .getContextualProperty(SecurityConstants.STS_CLIENT);
+        if (client == null) {
+            if (type == null) {
+                type = "";
+            } else {
+                type = "." + type + "-client";
+            }
+            client = new STSClient(message.getExchange().get(Bus.class));
+            Endpoint ep = message.getExchange().get(Endpoint.class);
+            client.setEndpointName(ep.getEndpointInfo().getName().toString() + type);
+            client.setBeanName(ep.getEndpointInfo().getName().toString() + type);
         }
+        return client;
+    }
+    public static STSClient getClient(Message message, String type, IssuedToken itok) {
         STSClient client = (STSClient)message
             .getContextualProperty(SecurityConstants.STS_CLIENT);
         if (client == null) {
+            if (type == null) {
+                type = "";
+            } else {
+                type = "." + type + "-client";
+            }
             client = new STSClient(message.getExchange().get(Bus.class));
             Endpoint ep = message.getExchange().get(Endpoint.class);
             client.setEndpointName(ep.getEndpointInfo().getName().toString() + type);
             client.setBeanName(ep.getEndpointInfo().getName().toString() + type);
+            if (itok.getIssuerEpr() != null) {
+                //configure via mex
+                client.configureViaEPR(itok.getIssuerEpr());
+            }
         }
         return client;
     }