How to create SAML assertion signature in node.js - node.js

I am working with an external api that requires me to create a saml assertion for mutual tls authentication. The client I am building to communicate with the api is written in nodejs. I was unable to find any libraries that would handle creating saml assertions for me so I ended up templating a saml assertion imported from an xml file and populated the necessary fields using handlebars. The only thing I am missing now is the signature, which I am having a hard time finding documentation on generating.
Here is an example of what I am trying to complete:
<ds:Signature>
<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="#_df0cbca2-3511-4586-b5f3-0211b1700413">
<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>{{fillMeIn}}</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>{{MeToo!}}</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>...secret...certificate...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
In the previous example I need values for the signature and digest, Any insight into how to generate these values would be appreciated. The ability to generate them dynamically (programatically) would be ideal. We are using self signed X509 certificates. Thanks in advance!

I found the xml-crypto library, which seems like it does what I am looking for.

Related

How to add `<Extensions>` element in SAML request using passport-saml?

I am using passport-saml as a SAML client and requesting to external IDP. I want to add <Extensions> element in SAML request like below:
<samlp:AuthnRequest AssertionConsumerServiceURL="https://iam.test.fi/oxauth/postlogin" Destination="https://testidp.fi/idp/profile/SAML2/Redirect/SSO" ID="_3a5525fc-f5cc-46af-add6-70bbc27ecebf" IssueInstant="2021-05-19T11:05:04Z" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://iam.test.fi/oxauth/1</saml:Issuer>
<samlp:Extensions>
<vetuma xmlns="urn:vetuma:SAML:2.0:extensions"><test>fi</test></vetuma>
</samlp:Extensions>
<samlp:NameIDPolicy AllowCreate="true"/>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://testidp.fi/2017/loa3</saml:AuthnContextClassRef>
</samlp:AuthnRequest>
I checked passport-saml config parameters but didn't find any one which gives facility to add <Exntesions> element.
Thank you.

Docusign API Integration for Real Estate Web Application

I'm developing a web application for real estate agents and their clients to easily handle offer management for real estate transactions. Using docusign's API, I'm hoping to allow my users to use embedded signing features to sign and submit documents regarding offers of their transaction.
The major issue/problem we want to solve is allowing local access to the docusign documents natively within our web application. Meaning, if a user submits a document on our platform, and requests multiple parties to sign the given document, we would like to keep a live copy within our application as it gets signed by multiple parties.
Currently, most implementations of the API simply send over the original document to docusign, and use their backend to update and notify parties when signatures have been requested or completed; meanwhile the original document submitted by the user to the platform, remains in it's original condition without any updates or changes; which can be confusing for users of the platform to keep track of the document status.
Any help in regards to solving this issue would be greatly appreciated. Is this possible? if so what tools and services are required to achieve this.
Meaning, if a user submits a document on our platform, and requests
multiple parties to sign the given document, we would like to keep a
live copy within our application as it gets signed by multiple
parties.
I have a couple suggestions. Let me know if either is what you're looking for:
First, you can call GET /envelopes/{envelopeId}/documents/{doucmentId} to retrieve docs from an envelope. Here's a link to more info on this endpoint.
Now, it also sounds like you may want to provide your realtor users with envelope status in real-time. There are a couple of ways to accomplish this, but one is greatly preferred.
Technically you CAN retrieve information about your envelopes by calling GET /envelopes?include=recipients,tabs. On your front end, this enables you to dynamically update components, such as a color-coded status column indicating to users where their agreements are in the pipeline. Downside here is that there are polling restrictions, which limit you to one such call every 15 minutes.
The preferred method is to use the Connect webhook notification service. When you create a connect configuration in your account, you can proactively receive information about your envelopes moments after events occur. (We'll ping you.) Then you can update front end components to keep your agents in the know.
Here's a sample connect notification:
<?xml version="1.0" encoding="utf-8"?>
<DocuSignEnvelopeInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.docusign.net/API/3.0">
<EnvelopeStatus>
<RecipientStatuses>
<RecipientStatus>
<Type>Signer</Type>
<Email>user.email#address.com</Email>
<UserName>User Name</UserName>
<RoutingOrder>1</RoutingOrder>
<Sent>2010-06-26T09:19:18.883</Sent>
<Delivered>2010-06-26T09:19:40.723</Delivered>
<DeclineReason xsi:nil="true" />
<Status>Delivered</Status>
<RecipientIPAddress>::1</RecipientIPAddress>
<CustomFields />
<TabStatuses>
<TabStatus>
<TabType>Custom</TabType>
<Status>Active</Status>
<XPosition>364</XPosition>
<YPosition>52</YPosition>
<TabLabel>Radio</TabLabel>
<TabName>Two</TabName>
<TabValue />
<DocumentID>1</DocumentID>
<PageNumber>2</PageNumber>
<OriginalValue />
<ValidationPattern />
<RoleName>TestRole</RoleName>
</TabStatus>
</TabStatuses>
<AccountStatus>Active</AccountStatus>
<RecipientId>fb89d2ee-2876-4290-b530-ff1833d5d0d2</RecipientId>
</RecipientStatus>
</RecipientStatuses>
<TimeGenerated>2010-06-26T09:19:45.771206-07:00</TimeGenerated>
<EnvelopeID>0aa561b8-b4d9-47e0-a615-2367971f876b</EnvelopeID>
<Subject>CreateEnvelopeFromTemplates Test</Subject>
<UserName>User Name</UserName>
<Email> user.email#address.com </Email>
<Status>Delivered</Status>
<Created>2010-06-26T09:16:21.27</Created>
<Sent>2010-06-26T09:19:19.01</Sent>
<Delivered>2010-06-26T09:19:40.747</Delivered>
<ACStatus>Original</ACStatus>
<ACStatusDate>2010-06-26T09:16:21.27</ACStatusDate>
<ACHolder>ACHolder Name</ACHolder>
<ACHolderEmail> ACHolder.email#address.com </ACHolderEmail>
<ACHolderLocation>ACHolder Location</ACHolderLocation>
<SigningLocation>Online</SigningLocation>
<SenderIPAddress>::1 </SenderIPAddress>
<EnvelopePDFHash />
<CustomFields>
<CustomField>
<Name>Envelope Field 1</Name>
<Show>False</Show>
<Required>False</Required>
<Value />
</CustomField>
<CustomField>
<Name>Envelope Field 2</Name>
<Show>False</Show>
<Required>False</Required>
<Value />
</CustomField>
</CustomFields>
<AutoNavigation>true</AutoNavigation>
<EnvelopeIdStamping>true</EnvelopeIdStamping>
<AuthoritativeCopy>false</AuthoritativeCopy>
<DocumentStatuses>
<DocumentStatus>
<ID>1</ID>
<Name>Document_Name</Name>
<TemplateName>radio parents</TemplateName>
<Sequence>1</Sequence>
</DocumentStatus>
</DocumentStatuses>
</EnvelopeStatus>
<DocumentPDFs>
<DocumentPDF>
<Name>DocumentPDF_Name</Name>
<PDFBytes>PDFBytes_Information</PDFBytes>
</DocumentPDF>
</DocumentPDFs>
</DocuSignEnvelopeInformation>

Why does my SAMLresponse received from ADFS not contain any claims?

I have setup ADFS and a NodeJS application to perform single-sign-on using ADFS as IdP.
I receive the SAMLreponse seen below.
When I receive the profile-object inside the verify function setup for the SAML-strategy, I see this:
{"issuer":"http://nonp-adfs.dsgapps.dk/adfs/services/trust"}
I need the profile to include at least the email or user ID of the logged in user.
How can I fix this?
SAMLresponse received:
<samlp:Response Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
Destination="https://localhost:3000/adfs/postResponse" ID="_e543e979-0d99-48fe-947f-1d1469da8c70"
InResponseTo="_49ab1e1060c3d7849902" IssueInstant="2018-06-28T19:46:27.782Z" Version="2.0"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://nonp-adfs.dsgapps.dk/adfs/services/trust</Issuer>
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
<Assertion ID="_cf245f57-1380-47cd-a5d3-05b13e4d9416" IssueInstant="2018-06-28T19:46:27.782Z"
Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>http://nonp-adfs.dsgapps.dk/adfs/services/trust</Issuer>
<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/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#_cf245f57-1380-47cd-a5d3-05b13e4d9416">
<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/2001/04/xmlenc#sha256"/>
<ds:DigestValue>r6voAsVq4yAJTn4BQLFsyaoiCK3b7KQbJ5jVqi53ceY=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>F55JA6jNp3qFfp7p/BSzQBRTtVPOlQvIfVNG3JiqjohVC7Et0+aiRVlHHvZNghPJxhmxhuAUbo2kOweN+lZKb+fqDgK51kZ/DrIVpkljmwP2gJYgOGpJti53wfH2qkdDsxNkR3e13mG7RKwBuA4gJ0NxUFshmxyun0HKefd10wjnFwHY6dELWFmTL1W5xd2ZF/98ahIaqEWAMCYsJewEg4ND8z4vG74miht3lWHfTJL6kQ0UGkTJVwGZy9L8zaY8AMDRujs8SlXvBx9nvUnvufpYqto4kd0O0USWMCOPipcF2sVYDOVzidRSRb79TK256Wg9EGiw1usVThfAJ8IBzQ==</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIC5DCCAcygAwIBAgIQWKHI7vunT6hIeNtPiejvbTANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNBREZTIFNpZ25pbmcgLSBub25wLWFkZnMuZHNnYXBwcy5kazAeFw0xODA2MTUxNDQ4NTdaFw0xOTA2MTUxNDQ4NTdaMC4xLDAqBgNVBAMTI0FERlMgU2lnbmluZyAtIG5vbnAtYWRmcy5kc2dhcHBzLmRrMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyN0SSHVjJML1lmcHB8RBNLXnegEISB66Nc75xEpscFGNPKoQloLck6XLPYvhmiL8WiVHTzghiJpU/faViR7s+wksj3n4IXVfCxb6wMd78LiOfeE6yyED+C/EprwoRWGXncUK4lwfLDGOPbWVqaPy0u14rQR0mvn0BsIOiML1JJvAPtf8fhavNmce2aEeRltLY3N8aoLMw8/TMrG+wk1imUo+JScp3gOPqrDnQBGgcjdBY/EaC9mFfAUbhyly0vKl/gYkOv1HFhUMtH7NlLUmDsvOCt3Nrbf6aKmi+H1EAfwJR/POnMbsoC8sqf4PWk/kMtj1POOpZAnQOBE8u4NtPwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDIdu6cr7LgoNdXpgtwd/Zt7sb1N6dJ/GgULuxBm7Bm1Mdsc9+Q0lDhxeGtay9AIvpbF67xvSzrCz3eL9xPuNV6BYmZpYFsyBPP4MROlkgq1MkqLDpkB/zkiKQqZiJG3RHl5e+WniFrAmNxuuUAtdhKbh1ADJKc1bxte6uiY0dN/Mfw6WnY3m3VOtae9xoqHNM2i4uhEbMvXV9Pmb8BVv4eIZLtOgo+vgkusp3FZa2PL4UWQIPNiEggIxhs7MfpaoADT4taGeavpHWKuxIGvDQzoe7GP2iDGzyH1kS24rSeJRYOiyBq1zPJHrSPeLFsef/7LapCaz5x5+T/eWPhyJKd</ds:X509Certificate>
</ds:X509Data>
</KeyInfo>
</ds:Signature>
<Subject>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><SubjectConfirmationData InResponseTo="_49ab1e1060c3d7849902"
NotOnOrAfter="2018-06-28T19:51:27.782Z" Recipient="https://localhost:3000/adfs/postResponse"/></SubjectConfirmation>
</Subject>
<Conditions NotBefore="2018-06-28T19:46:27.781Z" NotOnOrAfter="2018-06-28T20:46:27.781Z">
<AudienceRestriction>
<Audience>acme_tools_com</Audience>
</AudienceRestriction>
</Conditions>
<AuthnStatement AuthnInstant="2018-06-28T19:45:51.797Z">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
</samlp:Response>
It was very simple. From the Relying Party Trust Menu I could add the claims such as AD properties.

Centrify & Azure as IDP does not return LogoutResponse on Single Log Out

I'm trying to connect a SAML capable App as SP to Mircrosoft Azure and Centrify as IDP. SSO (Single Sign On) works as it should but i have some problems to accomplish a complete Single Logout Process.
When the user clicks on the logout button inside of the SP a (valid) logout request is sent to the IDP. The IDP session is terminated as expected but the browser is not redirected to the SP to complete the logout process. It seems as the LogoutResponse is completely missing.
UPDATE regarding Centrify
As Nick Gamb from Centrify stated (see his answer below) at this moment Centrify does not support this feature but will implement it in the future.
UPDATE regarding Azure
You have to provide a 'wreply' parameter - containing the url_ecoded URL of the site the user should be redirected to after logout - with the logout request:
https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0&wreply=https%3A%2F%2Fmyapp.landingpage.com%2F&SAMLRequest=...
If you are using the Onelogin PHP Toolkit, then you also have to enable the 'retrieveParametersFromServer'-Setting, otherwise the logout response will always end up with a 'Signature validation failed. Logout Request rejected' error.
Following the SAML requests/responses (i have allowed myself to strip out the certificate information ...):
Centrify // Login Request
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ONELOGIN_17b5cbaaa30c8a9edca9935a320b0de3a4088fcc"
Version="2.0"
ProviderName="MYAPP"
IssueInstant="2017-01-27T12:08:52Z"
Destination="https://aap1234.my.centrify.com/applogin/appKey/1234567-1234-1234-1234-123456789/customerId/ABC0123"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="https://myapp.com/acs"
>
<saml:Issuer>https://myapp.com/metadata</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>
Centrify // Login Response
<saml2p:Response ID="_7367bcc4-f4a1-4bf0-b845-ecaf0e7d6b86"
InResponseTo="ONELOGIN_17b5cbaaa30c8a9edca9935a320b0de3a4088fcc"
Version="2.0"
IssueInstant="2017-01-27T12:08:53.978Z"
Destination="https://myapp.com/acs"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
>
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://aap1234.my.centrify.com/1234567-1234-1234-1234-123456789</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#_7367bcc4-f4a1-4bf0-b845-ecaf0e7d6b86">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>EpN1bP9vKhLUUpyr0Hfnb3lM6gA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<Assertion Version="2.0"
ID="_71ccde7d-6a7b-4b79-a6ed-1f8465b7a835"
IssueInstant="2017-01-27T12:08:53.869Z"
xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
>
<Issuer>https://aap1234.my.centrify.com/1234567-1234-1234-1234-123456789</Issuer>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">centrify#myapp.com</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData NotOnOrAfter="2017-01-27T13:08:53.869Z"
Recipient="https://myapp.com/acs"
InResponseTo="ONELOGIN_17b5cbaaa30c8a9edca9935a320b0de3a4088fcc"
/>
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2017-01-27T12:05:53.869Z"
NotOnOrAfter="2017-01-27T13:08:53.869Z"
>
<AudienceRestriction>
<Audience>https://myapp.com/metadata</Audience>
</AudienceRestriction>
</Conditions>
<AuthnStatement AuthnInstant="2017-01-27T12:08:53.869Z"
SessionIndex="_71ccde7d-6a7b-4b79-a6ed-1f8465b7a835"
>
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
<AttributeStatement>
<Attribute Name="firstname"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
>
<AttributeValue>Firstname</AttributeValue>
</Attribute>
<Attribute Name="lastname"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
>
<AttributeValue>Lastname</AttributeValue>
</Attribute>
<Attribute Name="emailaddress"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
>
<AttributeValue>centrify#myapp.com</AttributeValue>
</Attribute>
<Attribute Name="groups"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
>
<AttributeValue>group1,group2</AttributeValue>
</Attribute>
</AttributeStatement>
</Assertion>
Centrify // Logout Request
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ONELOGIN_dc16bcf1e9a5de948d336fbca93d4a5718b56f3d"
Version="2.0"
IssueInstant="2017-01-27T12:10:12Z"
Destination="https://aap1234.my.centrify.com/applogout"
>
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">centrify#myapp.com</saml:NameID>
<samlp:SessionIndex>_71ccde7d-6a7b-4b79-a6ed-1f8465b7a835</samlp:SessionIndex>
Microsoft Azure // Login Request
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ONELOGIN_40becfa9c4dc2697c9778b7b598399fbc55cef98"
Version="2.0"
ProviderName="MYAPP"
IssueInstant="2017-01-27T12:31:26Z"
Destination="https://login.microsoftonline.com/1234567-1234-1234-1234-123456789/saml2"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="https://myapp.com/acs"
>
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
AllowCreate="true"
/>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
Microsoft Azure // Login Response
<samlp:Response ID="_4221c6ce-51b5-48df-b33e-5c601bbc22ad"
Version="2.0"
IssueInstant="2017-01-27T12:31:27.170Z"
Destination="https://myapp.com/acs"
InResponseTo="ONELOGIN_40becfa9c4dc2697c9778b7b598399fbc55cef98"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
>
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/1234567-1234-1234-1234-123456789/</Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<Assertion ID="_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e"
IssueInstant="2017-01-27T12:31:27.170Z"
Version="2.0"
xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
>
<Issuer>https://sts.windows.net/1234567-1234-1234-1234-123456789/</Issuer>
<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/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e">
<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/2001/04/xmlenc#sha256" />
<ds:DigestValue>mv1wKPg7iHLzZ5cNnu8oYX0/YvZqGsxKHsUc0umZVYw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>...</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">jMPrg5XmAUzfnoCKSAXJGJMDZ8Hdj_bRU2YY6-Ozugg</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData InResponseTo="ONELOGIN_40becfa9c4dc2697c9778b7b598399fbc55cef98"
NotOnOrAfter="2017-01-27T12:36:27.170Z"
Recipient="https://myapp.com/acs"
/>
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2017-01-27T12:26:27.154Z"
NotOnOrAfter="2017-01-27T13:26:27.154Z"
>
<AudienceRestriction>
<Audience>https://myapp.com/metadata</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
<AttributeValue>1234567-1234-1234-1234-123456789</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
<AttributeValue>12345-123-123-1234-12345678</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
<AttributeValue>live.com</AttributeValue>
</Attribute>
<Attribute Name="firstname">
<AttributeValue>Firstname</AttributeValue>
</Attribute>
<Attribute Name="lastname">
<AttributeValue>Lastname</AttributeValue>
</Attribute>
<Attribute Name="emailaddress">
<AttributeValue>mail#myapp.com</AttributeValue>
</Attribute>
</AttributeStatement>
<AuthnStatement AuthnInstant="2017-01-27T11:09:28.000Z"
SessionIndex="_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e"
>
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
Microsoft Azure // Logout Request
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ONELOGIN_a90edfe3da4eb07dd1e2a52df7d4cb5385cbd6c8"
Version="2.0"
IssueInstant="2017-01-27T12:32:05Z"
Destination="https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0"
>
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">jMPrg5XmAUzfnoCKSAXJGJMDZ8Hdj_bRU2YY6-Ozugg</saml:NameID>
<samlp:SessionIndex>_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e</samlp:SessionIndex>
The signout request is sent with additional GET parameters:
RelayState <= pointing to the Single Logout URL of the SP
wa <= set to „wsignout1.0“
I tested the SP configuration against a third IDP (Onelogin) and here the SP initiated logout works as expected. The user is logged out of the IDP session and then redirected with a LogoutResponse to the SP. The only difference here is that i'm able to set the SP Logout URL explicitly in the Onelogin App configuration.
Is there any option to define the SP logout url inside Azure or Centrify?
Am i missing anything?
Thanks!
As already mentioned in my updated question:
If you are using Centrify
As Nick Gamb from Centrify stated (see his answer above) at this moment Centrify does not support this feature but will implement it in the future.
If you are using Microsoft Azure
You have to provide a 'wreply' parameter - containing the url_ecoded URL of the site the user should be redirected to after logout - with the logout request: https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0&wreply=https%3A%2F%2Fmyapp.landingpage.com%2F&SAMLRequest=...
If you are using the Onelogin PHP Toolkit, then you also have to enable the 'retrieveParametersFromServer'-Setting, otherwise the logout response will always end up with a 'Signature validation failed. Logout Request rejected' error.
Thank you for submitting your question. This has been a common question as of late. The short answer is that Centrify does not support SAML single sign out at this time. The logout URL from the SAML app in Centrify is simply a logout request to the IDP. The user is always just redirected to the Centrify login page after. There is no SAML support in it thus no response.
The good news is that this feature is currently being addressed and should be released in a future build of the product to full SAML spec. Until that time, I have a possible solution for you to consider.
If you have the ability to modify your web application, specifically how it makes the logout call, you can set the logic up to make the logout call to the logout URL as an API call rather than a redirect. You will need to make the call to the logout URL from the sites Javascript so that the users session cookie is passed in the API call, as apposed to making it from server code. In doing this, you log the user out of Centrify but then you can redirect them to any page that you wish them to end up on (i.e. your web applications sign in page). The call does not require any JSON. Simply have a web request make the call to the logout url and then redirect the user to your login page.
Please feel free to follow up with me at devsupport#centrify.com and I will be happy to assist you further. I am also happy to have a call to discuss this in more detail.
Thank you,
Nick Gamb
Developer Advocate
Centrify

SAML Response - What needs to be verified to ensure the response can be trusted?

Apologies if these seems like a duplicate but I have been searching through the posts and I cannot find exactly what I am looking for.
My web application is sending an auth request to Azure for Single Sign On. Upon receipt of the response, what field and attributes need to be verified to ensure that the assertions can be trusted and why?
An example response is here from the Microsoft documentation-
<samlp:Response ID="_a4958bfd-e107-4e67-b06d-0d85ade2e76a" Version="2.0" IssueInstant="2013-03-18T07:38:15.144Z" Destination="https://contoso.com/identity/inboundsso.aspx" InResponseTo="id758d0ef385634593a77bdf7e632984b6" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> https://login.microsoftonline.com/82869000-6ad1-48f0-8171-272ed18796e9/</Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
</ds:Signature>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<Assertion ID="_bf9c623d-cc20-407a-9a59-c2d0aee84d12" IssueInstant="2013-03-18T07:38:15.144Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>https://login.microsoftonline.com/82869000-6ad1-48f0-8171-272ed18796e9/</Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
</ds:Signature>
<Subject>
<NameID>Uz2Pqz1X7pxe4XLWxV9KJQ+n59d573SepSAkuYKSde8=</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData InResponseTo="id758d0ef385634593a77bdf7e632984b6" NotOnOrAfter="2013-03-18T07:43:15.144Z" Recipient="https://contoso.com/identity/inboundsso.aspx" />
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2013-03-18T07:38:15.128Z" NotOnOrAfter="2013-03-18T08:48:15.128Z">
<AudienceRestriction>
<Audience>https://www.contoso.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
<AttributeValue>testuser#contoso.com</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
<AttributeValue>3F2504E0-4F89-11D3-9A0C-0305E82C3301</AttributeValue>
</Attribute>
...
</AttributeStatement>
<AuthnStatement AuthnInstant="2013-03-18T07:33:56.000Z" SessionIndex="_bf9c623d-cc20-407a-9a59-c2d0aee84d12">
<AuthnContext>
<AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
</samlp:Response>
What i know so far.
You must verify the signature to ensure the message has not been modified.
You must verify that the certificate public key is from a trusted source or else any validly signed certificate would authenticate.
What else?
The signature - remember to check the references.
Verify that the certificate is from the right peer (as you've noticed yourself)
The Conditions of the assertion.
I'd recommend that you do not write your own code for this and instead use an existing SAML2 SP library. Getting all of this right is a lot of work (I've done it, and I'm not sure I would if I had known how much work it is).

Resources