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

Aktuell sind unsere Stellen wieder alle besetzt, Initiativbewerbungen sind aber immer willkommen! - Weiterlesen
ITWU goes Libori 2025 oder Überlebensstress im Musikexpress - Weiterlesen
Spart Kosten & Frust: Professionelle Unterstützung beim HCL DLAU-Userbericht und der Userpflege - Weiterlesen
Lasertag und Grieche - eine vielversprechen Kombi für einen abenteuerlichen ITWU-Abend - Weiterlesen
Mit OIDC auf dem Vormarsch: Einfach und sicher REST-Aufrufe im HCL Notes-Client ohne Internetkennwort - Weiterlesen
Das Geheimnis hinter der sicheren HCL Notes Anmeldung und warum es das sogenannte "Internetkennwort" gibt - Weiterlesen
ITWU auf der Engage 2025 – Was waren die spannendsten Entwicklungsthemen? - Weiterlesen
 zum Archiv