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

ISIE Protokolleinträge – Teil 2: Wie legt ihr eine neue Log Entry Konfiguration an? - Weiterlesen
Entra (ehem. Azure) User einfach mit dem Domino Directory synchronisieren? So einfach geht’s! - Weiterlesen
ISIE Protokolleinträge: Das perfekte Logging-Tool zur einfachen Protokollierung von Aktionen in euren Anwendungen und Datenbanken! - Weiterlesen
Kein Bock mehr auf den Notes-Client? Dann nimm doch einfach deinen Webbrowser mit HCL Nomad Web! - Weiterlesen
ISIE Nummernkreise - Teil 2: Wie konfiguriere ich eine individuelle laufende Nummer in der ITWU Simple Integration Engine? - Weiterlesen
Unsere neue Karriere-Seite - Dein Weg bei der ITWU! - Weiterlesen
ITWU Stories - Dominik, wie begann dein Weg bei der ITWU und wo stehst du jetzt? - Weiterlesen
 zum Archiv