Hi, Do you have a good reasons not to use standard UsernameToken headers: https://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf https://web-gmazza.rhcloud.com/blog/entry/cxf-usernametoken-profile ?.
It is supported by CXF out of the box. To your question regarding thread.local.request.context: I don't think that it has significant performance influence, because CXF doesn't synchronizes calls, it just stores request parameters into thread local areas. Regards, Andrei. > -----Original Message----- > From: David Roytenberg (Consultant) > [mailto:[email protected]] > Sent: Donnerstag, 18. September 2014 15:54 > To: [email protected] > Subject: Best Practice for Passing SOAP Header Credentials Dynamically? > > I have created a SOAP client to an external web service using CXF 2.7.6 with a > WSDL-first approach. I've generated my client classes and used Spring to > instantiate my SOAP client. > > > > I am required to pass a username and password for injection into the SOAP > headers, and it is necessary to pick up that username and password > dynamically for each web service call. In the client code the SOAP headers > are > not yet accessible. I wrote an Interceptor to populate the SOAP headers and > used DOM to do it. > > > > To make the parameters available to my Interceptor, I used the CXF Request > Context. According to the documentation this can be made thread safe by > setting thread.local.request.context to true. > > > > My question is whether this could result in a performance bottlekneck. > Does this result in all messages synchronizing against the same request > context object? If so, is there another approach in CXF that would > avoid this? > > > > > > In the CXF client I put the user name and password into the CXF context like > this: > > > > private void passUserNameAndPassword(String userName, String password) { > > Client cxfClient = ClientProxy.getClient(myClient); > > // Per CXF documentation the following setting will make the context > thread > safe: > > > if(!"true".equals(cxfClient.getRequestContext().get("thread.local.reques > t.context"))) { > > cxfClient.getRequestContext().put("thread.local.request.context", > "true"); > > } > > // Now we can pass the credentials safely > > cxfClient.getRequestContext().put("userName", userName); > > cxfClient.getRequestContext().put("password", password); > > } > > > > > > My interceptor then pulls it out and puts it into the SOAP headers. I > include the > whole thing here in case it is useful to others. > > > > import java.util.Iterator; > > import java.util.List; > > import java.util.Map.Entry; > > import java.util.Set; > > > > import javax.xml.namespace.QName; > > > > import org.apache.cxf.binding.soap.SoapHeader; > > import org.apache.cxf.binding.soap.SoapMessage; > > import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; > > import > org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor; > > import org.apache.cxf.headers.Header; > > import org.apache.cxf.helpers.DOMUtils; > > import org.apache.cxf.interceptor.Fault; > > import org.apache.cxf.phase.Phase; > > import org.w3c.dom.Document; > > import org.w3c.dom.Element; > > > > public class SoapHeadersInterceptor extends AbstractSoapInterceptor > > { > > private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory > > .getLogger(SoapHeadersInterceptor.class); > > > > public SoapHeadersInterceptor() > > { > > super(Phase.PRE_STREAM); > > addBefore(SoapPreProtocolOutInterceptor.class.getName()); > > } > > > > > > @Override > > public void handleMessage(SoapMessage msg) throws Fault > > { > > logger.info("Called SoapHeadersInterceptor.handleMessage()!"); > > logger.info("SoapMessage enumeration"); > > Set<Entry<String,Object>> entrySet =msg.entrySet(); > > Iterator <Entry<String,Object>> sit = entrySet.iterator(); > > String userName=null; > > String password=null; > > while(sit.hasNext()) { > > Entry<String,Object> nextEntry= sit.next(); > > logger.info("Entry key: "+nextEntry.getKey()+", value: > "+nextEntry.getValue()); > > > > if("userName".equals(nextEntry.getKey())) { > > userName=(String)nextEntry.getValue(); > > } > > if("password".equals(nextEntry.getKey())) { > > password=(String)nextEntry.getValue(); > > } > > } > > > > List<Header> headers = msg.getHeaders(); > > > > Document d = DOMUtils.createDocument(); > > Element userNameElement = d.createElement("wsse:Username"); > > userNameElement.setTextContent(userName); > > logger.info("Setting userName to " + userName); > > Element passwordElement = d.createElement("wsse:Password"); > > passwordElement.setTextContent(password); > > logger.debug("Setting password to " + password); > > Element token = d.createElement("wsse:UsernameToken"); > > Element security = d.createElementNS( > > > "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sece > xt-1.0.xsd", > > "wsse:Security"); > > security.appendChild(token); > > token.appendChild(userNameElement); > > token.appendChild(passwordElement); > > > > SoapHeader securityHeader = new SoapHeader(new QName( > > > "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sece > xt-1.0.xsd", > > "wsse:Security"), security); > > securityHeader.setMustUnderstand(true); > > headers.add(securityHeader); > > } > > > > } > > > > Thanks for any insight you can offer. > > > > David > > -- > WARNING > ------- > This electronic message and its attachments may contain confidential, > proprietary or legally privileged information, which is solely for the use of > the > intended recipient. No privilege or other rights are waived by any unintended > transmission or unauthorized retransmission of this message. If you are not > the > intended recipient of this message, or if you have received it in error, you > should immediately stop reading this message and delete it and all > attachments from your system. The reading, distribution, copying or other use > of this message or its attachments by unintended recipients is unauthorized > and > may be unlawful. If you have received this e-mail in error, please notify the > sender. > > AVIS IMPORTANT > -------------- > Ce message electronique et ses pieces jointes peuvent contenir des > renseignements confidentiels, exclusifs ou legalement privilegies destines au > seul usage du destinataire vise. L'expediteur original ne renonce a aucun > privilege ou a aucun autre droit si le present message a ete transmis > involontairement ou s'il est retransmis sans son autorisation. Si vous > n'etes pas > le destinataire vise du present message ou si vous l'avez recu par erreur, > veuillez cesser immediatement de le lire et le supprimer, ainsi que toutes ses > pieces jointes, de votre systeme. La lecture, la distribution, la copie ou > tout > autre usage du present message ou de ses pieces jointes par des personnes > autres que le destinataire vise ne sont pas autorises et pourraient etre > illegaux. > Si vous avez recu ce courrier electronique par erreur, veuillez en aviser > l'expediteur.
