Hi,
I've succeeded in updating the username dynamically by following the
approach of extending WSS4JOutInterceptor :
Calling the super method and adding my own "internal" PhaseInterceptor at
the end of the interceptor chain, and in these one, walk through the header
to the username and update the value.
I guess it's an ugly way of doing things, if you have a better way of
doing, I'm listening.
Regards,
Thomas.
<bean class=*"com.tibco.cts.amxbpm.fwk.security.MyWSS4JOutInterceptor"*
id=*"outbound-security"*>
<constructor-arg>
<map>
<entry key=*"action"* value=*"UsernameToken"* />
<entry key=*"user"* value=*"tibco-admin"* />
<entry key=*"passwordType"* value=*"PasswordText"* />
<entry key=*"passwordCallbackClass"*
value=*
"com.tibco.cts.amxbpm.fwk.security.PasswordCallbackHandler"* />
</map>
</constructor-arg>
</bean>
*package* com.tibco.cts.amxbpm.fwk.security;
*import* java.util.Collection;
*import* java.util.Collections;
*import* java.util.Iterator;
*import* java.util.Map;
*import* java.util.Set;
*import* javax.xml.namespace.QName;
*import* javax.xml.soap.SOAPElement;
*import* javax.xml.soap.SOAPException;
*import* javax.xml.soap.SOAPFactory;
*import* javax.xml.soap.SOAPHeader;
*import* javax.xml.soap.SOAPMessage;
*import* org.apache.cxf.binding.soap.SoapMessage;
*import* org.apache.cxf.interceptor.Fault;
*import* org.apache.cxf.phase.Phase;
*import* org.apache.cxf.phase.PhaseInterceptor;
*import* org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
*public* *class* MyWSS4JOutInterceptor *extends* WSS4JOutInterceptor
{
*private* MyWSS4JOutInterceptorInternal ending;
*public* MyWSS4JOutInterceptor(Map<String, Object> props)
{
*super*();
setProperties(props);
*this*.ending = *new* MyWSS4JOutInterceptorInternal();
}
@Override
*public* *void* handleMessage(SoapMessage soapMessage) *throws* Fault
{
*super*.handleMessage(soapMessage);
soapMessage.getInterceptorChain().add(ending);
}
}
*final* *class* MyWSS4JOutInterceptorInternal
*implements*PhaseInterceptor<SoapMessage>
{
*public* MyWSS4JOutInterceptorInternal()
{
*super*();
}
@Override
*public* *void* handleMessage(SoapMessage soapMessage) *throws* Fault
{
SOAPMessage sm = soapMessage.getContent(SOAPMessage.*class*);
*try*
{
SOAPFactory sf = SOAPFactory.*newInstance*();
SOAPHeader sh = sm.getSOAPHeader();
*if* (sh == *null*)
{
sh = sm.getSOAPPart().getEnvelope().addHeader();
}
QName wsseSecurity = *new* QName("
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
", "Security", "wsse");
Iterator<SOAPElement> securityIterator =
sh.getChildElements(wsseSecurity);
*if* (securityIterator.hasNext())
{
SOAPElement securityElement = securityIterator.next();
QName usernameToken = *new* QName("
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
", "UsernameToken", "wsse");
Iterator<SOAPElement> usernameTokenIterator =
securityElement.getChildElements(usernameToken);
*if* (usernameTokenIterator.hasNext())
{
SOAPElement usernameTokenElement = usernameTokenIterator.next();
QName username = *new* QName("
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
", "Username", "wsse");
Iterator<SOAPElement> usernameIterator =
usernameTokenElement.getChildElements(username);
*if* (usernameIterator.hasNext())
{
usernameIterator.next().setValue("toto");
}
}
}
}
*catch* (SOAPException e)
{
*throw* *new* Fault(e);
}
}
*public* Set<String> getAfter()
{
*return* Collections.*emptySet*();
}
*public* Set<String> getBefore()
{
*return* Collections.*emptySet*();
}
*public* String getId()
{
*return* MyWSS4JOutInterceptorInternal.*class*.getName();
}
*public* String getPhase()
{
*return* Phase.*POST_PROTOCOL*;
}
*public* *void* handleFault(SoapMessage message)
{
// nothing
}
*public* Collection<PhaseInterceptor<?
*extends*org.apache.cxf.message.Message>>
getAdditionalInterceptors() {
*return* *null*;
}
}
On Fri, Oct 18, 2013 at 5:04 PM, Thomas Manson
<[email protected]>wrote:
> Hi,
>
> I'm trying to call a webservice and dynamically change the username.
>
> To do that I've tried to add a CXF interceptor that would update the
> current username setted by WSS4JOutInterceptor.
>
> Unfortunately, I didn't succeed to make my interceptor to get executed
> after WSS4JOutInterceptor so the SoapHeader is empty.
>
> I've tried that :
>
> public class SecurityCxfInterceptor extends AbstractSoapInterceptor
>
> {
>
> public SecurityCxfInterceptor()
>
> {
>
> super(Phase.PRE_PROTOCOL);
>
>
>
> // this.getAfter().add(SAAJOutInterceptor.class.getName());
>
> // this.getBefore().add(WSS4JOutInterceptor.class.getName());
>
> this.addAfter(SecurityCxfInterceptor.class.getName());
>
> }
>
> with this spring configuration
>
>
> <bean id="SecurityCxfInterceptor"
> class="com.tibco.cts.amxbpm.fwk.security.SecurityCxfInterceptor" />
>
>
> <cxf:bus>
> <cxf:features>
> <p:policies />
> <cxf:logging />
> </cxf:features>
> <cxf:outInterceptors>
> <ref bean="SecurityCxfInterceptor" />
> </cxf:outInterceptors>
> </cxf:bus>
>
>
> And I've aslo tried to extend WSS4JOutInterceptor but it doesn't work,
> as WSS4JOutInterceptor just add an EndingInterceptor which point to an
> internal call that does the job.
>
>
> Can somebody put me on the correct track to have my interceptor exectued
> after WSS4JOutInterceptor so that I can update the username?
>
>
>
> Thanks,
>
> Thomas.
>
>
>