Using soap header to authenticate user in stateless mode

Using Delphi with the latest ROSDK:

We are implementing a service that will require the client to send user id and password in the soap header on each method call.

I see that TROSoapMessage has a HeaderNode property, but which event would I use to evaluate that header?

Thank you.

you can use OnGetDispatchInfo event like

procedure TMegaDemoService.RORemoteDataModuleGetDispatchInfo(const aTransport: IROTransport;
  const aMessage: IROMessage);
var
  k: IXMLNode;
  soap: IROSOAPMEssage;
begin
  if Supports(aMessage, IROSOAPMEssage, soap) then begin
    k := soap.HeaderNode;
    // do something
  end;
end;

Thanks Evgeny - that works perfectly.

However, how can we update the WSDL in our server so that the client that implements the WSDL is aware that the username and password are required in the header?

so do you want to send username&password at each client request?
we send ROClientIDHeader tag that specifies client session if on server-side by default in ROD

Yes, the client would send user-id/password on each request in the header. The customer of this API cannot handle session tracking on their side, so they don’t want/can’t use the ROClientIDHeader.

The service is working for them if they manually modify the header on their side, but they would like the .Net importer to parse the WSDL and create the header class for them.

pls read this article - Tip: Implement implicit and explicit SOAP headers

Thank you Evgeny, that is certainly an interesting article.

Is there an event in RemObjects that allows us to inject these implicit or explicit headers? I haven’t had any luck finding one yet.

you can use OnEnvelopeComplete event of TROSOAPMessage

We have already tried the suggested solution of using OnEnvelopeComplete to adjust the outgoing WSDL. The problem is OnEnvelopeComplete doesn’t fire on the server when a client requests the WSDL. After looking through the TROSOAPMessage object, it looks like the GetModuleInfo method is responsible for converting the RODL spec into a WSDL spec. We haven’t been to find an event that lets us manipulate the WSDL content before it is sent back in a response.

this is a bit tricky.
declare this class near to your server:

TMySOAPMessage = class(TROSOAPMessage)
protected
  procedure GetModuleInfo(aStream : TStream; const aTransport : IROTransport; var aFormat : TDataFormat); override;
end;

procedure TMySOAPMessage.GetModuleInfo(aStream: TStream; const aTransport: IROTransport; var aFormat: TDataFormat);
begin
  inherited GetModuleInfo(aStream, aTransport, aFormat);
  // modify content of stream 
end;

register it instead of std TROSOAPMessage:

procedure TServerForm.FormCreate(Sender: TObject);
var
  fdisp : TROHTTPDispatcher;
begin
  fdisp := TROHTTPDispatcher(ROServer.Dispatchers.Add);
  fdisp.Message := TMySOAPMessage.Create(Self);
  fdisp.PathInfo := '/soap';
  ROServer.Active := true;
end;

Thank you. Your information was very useful, and helped us add the desired extra WSDL details.