Today I like to share a simple but elegant and reusable solution to implement Web Service Security (WSS) into Domino Web Service Consumers.

Let's assume you already generated your Web Service Consumer Stub from the WSDL which means you have a class called <WebServicePackage>.<WebServiceName>Stub.

Example:

 

The stub should look something like this:

package com.atradius.connect._2007_08;

 

public class CoverPortfolioSynchronisationStub

  extends lotus.domino.websvc.client.Stub

  implements com.atradius.connect._2007_08.CoverPortfolioSynchronisation {

 

  public CoverPortfolioSynchronisationStub(

       java.net.URL endpointURL,

       javax.xml.rpc.Service service )

  throws lotus.domino.types.Fault

  {

     super(endpointURL, service);

  }

 

  public void retrievePortfolio(

       java.util.Date dateFrom,

       java.util.Date dateTo,

       com.atradius.connect._2007_08.PoliciesType policies,

       javax.xml.rpc.holders.BigIntegerHolder numberOfCovers,

       javax.xml.rpc.holders.ByteArrayHolder portfolioCovers,

       javax.xml.rpc.holders.StringHolder mimeType,

       javax.xml.rpc.holders.StringHolder contentType)

  throws

  com.atradius.services.exception._2006_12_15.exception.WSException,

  java.rmi.RemoteException

  {

     lotus.domino.websvc.client.Call _call =

       createCall("retrievePortfolio");

 

     java.lang.Object _resp =

       _call.invoke(

            new java.lang.Object[] {dateFrom, dateTo, policies});

 

     numberOfCovers.value =

       (java.math.BigInteger) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "NumberOfCovers",

            java.math.BigInteger.class);

 

     portfolioCovers.value =

       (byte[]) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "PortfolioCovers",

            byte[].class);

 

     mimeType.value =

       (java.lang.String) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "MimeType",

            java.lang.String.class);

 

     contentType.value =

       (java.lang.String) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "ContentType",

            java.lang.String.class);

  }

}

 

Note that the stub extends “lotus.domino.websvc.client.Stub. The easiest way to enable the client to pass SOAP credentials is for us to use our own Stub base class “mypackage.Stub” which in turn inherits “lotus.domino.websvc.client.Stub”.

Extended Stub:

package de.itwu.utils.websvc.client;

 

import java.net.URL;

 

import javax.xml.rpc.Service;

import javax.xml.soap.SOAPElement;

import javax.xml.soap.SOAPException;

 

import lotus.domino.axis.message.PrefixedQName;

import lotus.domino.axis.message.SOAPHeaderElement;

import lotus.domino.types.Fault;

 

public class Stub

  extends lotus.domino.websvc.client.Stub {

 

  public Stub( Service service, String url ) {

     super( service, url );

  }

 

  public Stub( URL endpointURL, Service service ) throws Fault {

     super( endpointURL, service );

  }

 

  protected SOAPHeaderElement getSOAPHeaderSecurity(){

     try{

 

       final PrefixedQName secHeaderQN =

          new PrefixedQName(

                  "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",

                  "Security",

                  "wsse" );

       final PrefixedQName passTypeQN =

          new PrefixedQName(

                  "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",

                  "Type",

                  "wsse" );

      

       final SOAPHeaderElement security = new SOAPHeaderElement( secHeaderQN );

       security.setMustUnderstand( true );

 

       final SOAPElement usernameToken = security.addChildElement( "UsernameToken", "wsse" );

 

       final SOAPElement username = usernameToken.addChildElement( "Username", "wsse" );

       username.addTextNode( this.getUsername() );

 

       final SOAPElement password = usernameToken.addChildElement( "Password", "wsse" );

       password.addAttribute(

            passTypeQN,

            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" );

       password.addTextNode( this.getPassword() );

 

       return security;

     } catch (SOAPException e) {

       e.printStackTrace();

     }

     return null;

  }

}

 

Our stub implements a new method which constructs and returns the necessary SOAP message header to authenticate to the provider through a username and a clear-text password.
The schema is defined in http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd.

Please note that the above method makes use of getPassword()and getUsername(). Those are built-in getters which retrieve the credentials that have been set through setCredentials().

Now all we have to do is to modify the generated stub. First we change the inheritance, the stub now should inherit from our newly written base.  After that is done we add the following method call to all web service calls:

  _call.addHeader(getSOAPHeaderSecurity());

 

Example:

package com.atradius.connect._2007_08;

 

public class CoverPortfolioSynchronisationStub

  extends de.itwu.utils.websvc.client.Stub

  implements com.atradius.connect._2007_08.CoverPortfolioSynchronisation {

 

  public CoverPortfolioSynchronisationStub(

       java.net.URL endpointURL,

       javax.xml.rpc.Service service )

  throws lotus.domino.types.Fault

  {

    super(endpointURL, service);

  }

 

  public void retrievePortfolio(

       java.util.Date dateFrom,

       java.util.Date dateTo,

       com.atradius.connect._2007_08.PoliciesType policies,

       javax.xml.rpc.holders.BigIntegerHolder numberOfCovers,

       javax.xml.rpc.holders.ByteArrayHolder portfolioCovers,

       javax.xml.rpc.holders.StringHolder mimeType,

       javax.xml.rpc.holders.StringHolder contentType)

  throws

  com.atradius.services.exception._2006_12_15.exception.WSException,

  java.rmi.RemoteException

  {

     lotus.domino.websvc.client.Call _call =

       createCall("retrievePortfolio");

 

     _call.addHeader(getSOAPHeaderSecurity());

 

     java.lang.Object _resp =

       _call.invoke(

            new java.lang.Object[] {dateFrom, dateTo, policies});

 

     numberOfCovers.value =

       (java.math.BigInteger) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "NumberOfCovers",

            java.math.BigInteger.class);

 

     portfolioCovers.value =

       (byte[]) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "PortfolioCovers",

            byte[].class);

 

     mimeType.value =

       (java.lang.String) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "MimeType",

            java.lang.String.class);

 

     contentType.value =

       (java.lang.String) _call.convertOutputParam(

            "http://atradius.com/connect/_2007_08/",

            "ContentType",

            java.lang.String.class);

  }

}

 

Done. Now all SOAP requests will have the specified wss header. Just don’t forget to actually set the credentials in your code ;-).

 

CoverPortfolioSynchronisation stub = new AtradiusConnectSynchronisationServiceLocator().getCoverPortfolioSynchronisation();

       stub.setEndpoint( url);

       stub.setCredentials( "user", "password" );

       stub.retrievePortfolio(

          startDate,

          new Date(),

          policies,

       numberOfCovers,

       portfolioCovers,

       mimeType,

       contentType);

 

The complete wss specification can be found at:

http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf

http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf

 

 

Neues vom ITWU-Blog

Unsere ITWU Simple Integration Engine – An einer Stelle konfigurieren und mit dem gängigen Standard per REST-Aufruf ganz „ISIE“ überall nutzen! - Weiterlesen
ITWU-Projektvorstellung: Die kluge Scan-Lösung - Automatisiert Lieferscheine scannen und prozessintegriert verarbeiten mit dem Canon Scan-Import - Weiterlesen
Das neue HCL Download-Portal My HCLSoftware (MHS), EOS Domino V11 und Sametime V11.5 - Weiterlesen
HCL Lizenz Update: Umstellung auf Complete Collaboration Lizenzen (CCB), EOM und EOS für alte Lizenztypen und Änderungen der jährlichen Preissteigerung - Weiterlesen
Update-Info: HCL Notes Domino 14 Fix Pack 1 - Weiterlesen
Mit ITWU Simple Signature automatisch generierte HTML-Mailsignaturen für HCL Verse und Notes erstellen - Weiterlesen
ITWU-Projektvorstellung: Digitale Werkszeugnisse automatisch erzeugen, standardisiert und transparent - so geht smarte Qualitätssicherung! - Weiterlesen
 zum Archiv