Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Create AuthNRequest with embedded signature (HTTP-POST binding)

See more XML Digital Signatures Examples

Demonstrates how to create a SAML AuthNRequest with embedded signature (HTTP-POST binding).

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.StringBuilder,
  Chilkat.XmlDSigGen,
  Chilkat.Xml,
  Chilkat.XmlDSig,
  Chilkat.Cert;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  xmlToSign: TXml;
  gen: TXmlDSigGen;
  cert: TCert;
  sbXml: TStringBuilder;
  verifier: TXmlDSig;
  verified: Boolean;

begin
  success := False;

  //  This example requires the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  //  This example will sign the following SAML AuthNRequest:

  //  <samlp:AuthnRequest 
  //       xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  //       xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
  //       ID="pfx41d8ef22-e612-8c50-9960-1b16f15741b3"
  //       Version="2.0" ProviderName="SP test" IssueInstant="2014-07-16T23:52:45Z"
  //       Destination="http://idp.example.com/SSOService.php"
  //       ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
  //       AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs">
  //    <saml:Issuer>http://sp.example.com/demo1/metadata.php</saml:Issuer>
  //    <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
  //    <samlp:RequestedAuthnContext Comparison="exact">
  //      <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
  //    </samlp:RequestedAuthnContext>
  //  </samlp:AuthnRequest>

  //  First we build the XML to be signed.
  //  
  //  Use this online tool to generate the code from sample XML: 
  //  Generate Code to Create XML

  success := True;
  xmlToSign := TXml.Create;
  xmlToSign.Tag := 'samlp:AuthnRequest';
  xmlToSign.AddAttribute('xmlns:samlp','urn:oasis:names:tc:SAML:2.0:protocol');
  xmlToSign.AddAttribute('xmlns:saml','urn:oasis:names:tc:SAML:2.0:assertion');
  xmlToSign.AddAttribute('ID','pfx41d8ef22-e612-8c50-9960-1b16f15741b3');
  xmlToSign.AddAttribute('Version','2.0');
  xmlToSign.AddAttribute('ProviderName','SP test');
  xmlToSign.AddAttribute('IssueInstant','2014-07-16T23:52:45Z');
  xmlToSign.AddAttribute('Destination','http://idp.example.com/SSOService.php');
  xmlToSign.AddAttribute('ProtocolBinding','urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST');
  xmlToSign.AddAttribute('AssertionConsumerServiceURL','http://sp.example.com/demo1/index.php?acs');
  xmlToSign.UpdateChildContent('saml:Issuer','http://sp.example.com/demo1/metadata.php');
  xmlToSign.UpdateAttrAt('samlp:NameIDPolicy',True,'Format','urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress');
  xmlToSign.UpdateAttrAt('samlp:NameIDPolicy',True,'AllowCreate','true');
  xmlToSign.UpdateAttrAt('samlp:RequestedAuthnContext',True,'Comparison','exact');
  xmlToSign.UpdateChildContent('samlp:RequestedAuthnContext|saml:AuthnContextClassRef','urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport');

  //  Also see the online tool to generate the code from sample already-signed XML: 
  //  Generate XML Signature Creation Code from an Already-Signed XML Sample

  gen := TXmlDSigGen.Create;

  gen.SigLocation := 'samlp:AuthnRequest';
  gen.SigNamespacePrefix := 'ds';
  gen.SigNamespaceUri := 'http://www.w3.org/2000/09/xmldsig#';
  gen.SignedInfoCanonAlg := 'EXCL_C14N';
  gen.SignedInfoDigestMethod := 'sha1';

  //  -------- Reference 1 --------
  gen.AddSameDocRef('pfx41d8ef22-e612-8c50-9960-1b16f15741b3','sha1','EXCL_C14N','','');

  //  Provide a certificate + private key. (PFX password is test123)
  cert := TCert.Create;
  success := cert.LoadPfxFile('qa_data/pfx/cert_test123.pfx','test123');
  if (success <> True) then
    begin
      WriteLn(cert.LastErrorText);
      Exit;
    end;
  gen.SetX509Cert(cert,True);

  gen.KeyInfoType := 'X509Data';
  gen.X509Type := 'Certificate';

  //  Load XML to be signed...
  sbXml := TStringBuilder.Create;
  xmlToSign.GetXmlSb(sbXml);

  gen.Behaviors := 'IndentedSignature,ForceAddEnvelopedSignatureTransform';

  //  Sign the XML...
  success := gen.CreateXmlDSigSb(sbXml);
  if (success <> True) then
    begin
      WriteLn(gen.LastErrorText);
      Exit;
    end;

  //  Save the signed XMl to a file.
  success := sbXml.WriteFile('qa_output/signedXml.xml','utf-8',False);

  //  A sample of the signed XML is shown below..
  WriteLn(sbXml.GetAsString());

  //  ----------------------------------------
  //  Verify the signature we just produced...
  verifier := TXmlDSig.Create;
  success := verifier.LoadSignatureSb(sbXml);
  if (success <> True) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  verified := verifier.VerifySignature(True);
  if (verified <> True) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;
  WriteLn('This signature was successfully verified.');

  //  -----------------------------------------
  //  Sample output of AuthNRequest signed XML:
  //  (Line-breaks and some indenting added for readability..)

  //  <?xml version="1.0" encoding="utf-8"?>
  //  <samlp:AuthnRequest 
  //    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
  //    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
  //    ID="pfx41d8ef22-e612-8c50-9960-1b16f15741b3" 
  //    Version="2.0" ProviderName="SP test" 
  //    IssueInstant="2014-07-16T23:52:45Z" 
  //    Destination="http://idp.example.com/SSOService.php" 
  //    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" 
  //    AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs">
  //      <saml:Issuer>http://sp.example.com/demo1/metadata.php</saml:Issuer>
  //      <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
  //      <samlp:RequestedAuthnContext Comparison="exact">
  //          <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
  //      </samlp:RequestedAuthnContext>
  //  	<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  //  	  <ds:SignedInfo>
  //  	    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
  //  	    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
  //  	    <ds:Reference URI="#pfx41d8ef22-e612-8c50-9960-1b16f15741b3">
  //  	      <ds:Transforms>
  //  	        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
  //  	        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
  //  	      </ds:Transforms>
  //  	      <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
  //  	      <ds:DigestValue>5d+/YNShy4qnvZcvik8fHHg2SWQ=</ds:DigestValue>
  //  	    </ds:Reference>
  //  	  </ds:SignedInfo>
  //  	  <ds:SignatureValue>QS16H5...U5LQ==</ds:SignatureValue>
  //  	  <ds:KeyInfo>
  //  	    <ds:X509Data>
  //  	      <ds:X509Certificate>MIIF...tjlF4=</ds:X509Certificate>
  //  	    </ds:X509Data>
  //  	  </ds:KeyInfo>
  //  	</ds:Signature>
  //  </samlp:AuthnRequest>
  //  


  xmlToSign.Free;
  gen.Free;
  cert.Free;
  sbXml.Free;
  verifier.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.