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

Neues Video zum digitalen Montagearbeitsbericht – immer alle Infos dabei, mobil und offline! - Weiterlesen
Unser zweiter Teamtag bei den OWL-Games - Weiterlesen
Gültige E-Rechnungen individuell und datensicher on-Premises erstellen - Weiterlesen
KI-Antworten und ihre Tücken – Von der Bedeutung des kritischen Hinterfragens souverän vorgetragener Antworten - Weiterlesen
Sicher und souverän unterwegs: BSI-Zertifizierung „IT-Grundschutz“ mit HCL Domino möglich! - Weiterlesen
Azubi-Insights bei ITWU: Robin im Gespräch - Weiterlesen
Die Montage im Blick: So einfach verplant ihr Ressourcen für eure Aufträge - Weiterlesen
 zum Archiv