6

I've been pulling my hair out over this one and I just can't get it to work. I have a webservice I call that generates a security token which then needs to be passed to the subsequent service calls inside of the SOAP header. I got that part working just fine but the header part is tripping me up (I generated the client using cxf wsdl2java). This is the part that should be added:

<wsse:BinarySecurityToken ValueType="XXXX" EncodingType="wsse:Base64Binary" wsu:Id="SecurityToken">
  My token
</wsse:BinarySecurityToken>

I tried using a WSS4JOutInterceptor like this:

Endpoint endpoint = client.getEndpoint();
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put("SecurityToken", MY-TOKEN);
endpoint.getOutInterceptors().add(new WSS4JOutInterceptor(outProps));

but that didn't work. And I tried directly adding it to the header like this (as per this question):

List<Header> headers = new ArrayList<Header>();
SOAPFactory sf = SOAPFactory.newInstance();
SOAPElement authElement = sf.createElement(new QName(null, "wsse:BinarySecurityToken"));
authElement.setAttribute("ValueType", "XXXX");
authElement.setAttribute("EncodingType", "wsse:Base64Binary");
authElement.setAttribute("wsu:Id", "SecurityToken");
authElement.addTextNode(MY-TOKEN);
SoapHeader tokenHeader = new SoapHeader(
  new QName(null, "wsse:BinarySecurityToken"), authElement);
headers.add(tokenHeader);
((BindingProvider) service).getRequestContext().put(Header.HEADER_LIST, headers);

and it looks almost ok

<soap:Header><BinarySecurityToken EncodingType="wsse:Base64Binary" ValueType="XXXX" wsu:Id="SecurityToken">MY-TOKEN</BinarySecurityToken></soap:Header>

The BinarySecurityToken part is missing the wsse: prefix though and the call fails.

Has anyone gotten something similar to work – or am I doing it completely wrong?

Community
  • 1
  • 1
Jan Gorman
  • 1,004
  • 2
  • 11
  • 16

2 Answers2

6

@zengr Yes, I finally figured it out, it was missing the namespaces so what I did was this:

private static final String XMLNS_WSU = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
private static final String XSD_WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

final List<Header> headers = new ArrayList<Header>();
final SOAPFactory sf = SOAPFactory.newInstance();
final SOAPElement securityElement = sf.createElement("Security", "wsse", XSD_WSSE);
final SOAPElement authElement = sf.createElement("BinarySecurityToken", "wsse", XSD_WSSE);
authElement.setAttribute("ValueType", "WASP");
authElement.setAttribute("EncodingType", "wsse:Base64Binary");
authElement.setAttribute("wsu:Id", "SecurityToken");
authElement.addAttribute(new QName("xmlns:wsu"), XMLNS_WSU);
authElement.addTextNode(StringUtils.replace(SessionToken.getEncodedSessionToken(), "\n", ""));
securityElement.addChildElement(authElement);
final SoapHeader securityHeader = new SoapHeader(
        new QName(null, "Security"), securityElement);
headers.add(securityHeader);
((BindingProvider) interactiveService).getRequestContext().put(Header.HEADER_LIST, headers);

And that did the trick

Jan Gorman
  • 1,004
  • 2
  • 11
  • 16
  • Thanks, I figured out the same thing, hard way ;) – zengr Sep 15 '11 at 17:10
  • Dear @Jan what should be the content of SessionToken.getEncodedSessionToken() method? Does it return GUID? – Winston Nov 17 '14 at 14:05
  • 1
    @WinstonSmith really sorry but this is such a long time ago… I'll check in the office tomorrow if the code is still around. You might have more luck checking out .net related stuff in the meantime. – Jan Gorman Nov 17 '14 at 21:34
  • Can you help me in my question? I'm using axis2 instead of cxf, I don't have those methods to add headers (i'm using similar) but I can switch to cxf, I just need to sign the soap message https://stackoverflow.com/questions/63482746/adding-binarysecuritytoken-to-a-wsdl2java-client-generated-axis2 – Alejandro L. Aug 20 '20 at 09:06
2

Thank you. I had similar case except I had to add token within an element of an element under header. This is trivial, but I paste solution here for more complete documentation.

    String token = "authentication token given from service";
    SOAPFactory sf = SOAPFactory.newInstance();
    SOAPElement authElement = sf.createElement(new QName("urn:example.com", "Authentication"));
    SOAPElement tokenElement = sf.createElement(new QName(null, "AuthenticationToken"));
    tokenElement.addTextNode(token);
    authElement.addChildElement(tokenElement);
    List<Header> headers = new ArrayList<Header>();
    Header dummyHeader = new Header(new QName("urn:example.com"), authElement); 
    headers.add(dummyHeader);

which resulted in

<S:Header><Authentication xmlns="urn:example.com"><AuthenticationToken>authentication token given from service</AuthenticationToken></Authentication></S:Header>
ilvez
  • 1,235
  • 3
  • 16
  • 27