Skip to content

passport-saml's IdP initiated LogoutRequest handling doesn't always close sessions #419

@srd90

Description

@srd90

It's possible that passport-saml responds to IdP initiated logout request that sessions are closed even though sessions are still alive. This can happen at least in following situation:

  1. end user has blocked third party cookies
  2. SAML IdP is at another top level domain than SAML SP (passport-saml) application. Ie. SAML SP site is "third party site" from browsers' cookie handling point of view when browser is rendering page at SAML IdP site.
  3. end user triggers global logout from some other service (passport-saml receives IdP initiated LogoutRequest)
  4. SAML IdP has implemented logout propagation with combination of iframes and javascripts

Possible result from end use point of view: IdP reports that session related to passport-saml site is successfully closed even though it is not touched during logout process in anyway.

This problem has potential to hit a lot of end users when chrome starts to block third party cookies by default.

Following code is sending LogoutRequests to passport-saml like

  • browser without third party cookie blocking enabled
  • browser with third party cookie block enabled

console.logs written by example code are available at the end of the issue.

"use strict";

// Purpose: to demonstrate LogoutRequest handling issue.
// Drop this code to passport-saml's test/ directory and run tests.
// This is not meant to be added to passport-saml's testsuite as-is.
// This test code was "tested" against passport-saml version ac7939fc1f74c3a350cee99d68268de7391db41e
//
// Add following libraries to devDependencies
//   "supertest": "4.0.2",
//   "express-session": "1.17.0",
//   "cookie-parser": "1.4.4",
//   "chai": "4.2.0",
//   "chai-string": "1.5.0",
//   "memorystore": "1.6.1",
//   "cookiejar": "2.1.2"
//
//
//
const express = require("express");
const session = require("express-session");
const passport = require("passport");
const bodyParser = require("body-parser");
const SamlStrategy = require("../lib/passport-saml/index.js").Strategy;
const memorystore = require("memorystore")(session)

const supertest = require("supertest");
const chai = require("chai");
chai.use(require("chai-string"));
const expect = chai.expect;
const url = require("url");
const zlib = require("zlib");
const xmldom = require("xmldom");
const SignedXml = require("xml-crypto").SignedXml;
const fs = require("fs");
const xml2js = require("xml2js");
const cookiejar = require("cookiejar");


// These constants do not play any other role except to highlight
// that in order to replicate this issue with live SAML IdP & SP
// you have to setup those to different domains.
//
// SP must be in a domain which is from browsers' cookie handlng point
// of view a third party site when browser is executing SLO orchestration
// scripts at IdP site.
//
// For additional information about IdPs SLO behaviour / configuration:
// https://wiki.shibboleth.net/confluence/display/IDP30/LogoutConfiguration#LogoutConfiguration-Overview
// https://simplesamlphp.org/docs/stable/simplesamlphp-idp-more#section_1
const SAML_SP_DOMAIN = "passport-saml-powered-SAML-SP.qwerty.local";
const IDENTITY_PROVIDER_DOMAIN = "identity-provider.asdf.local";

// these endpoints consume:
// - IdP's responses to SP initiated login
// - IdP's responses to SP initiated logout (SLO logout responses with status of SLO process
//   if user return from IdP to SP after SLO has been complited by IdP)
// - IdP initiated logout request when another SP which participates to same SSO
//   session has triggered SLO. IdP ends up propagating logout request to this SAML SP instance.
//   SP must respond with SAML logout response message which contains result of logout request
//   processing at SP side (if session designated by logout request was terminated successfully along
//   with possible application level sessions).
//
// Names/paths of these endpoints reflect these concepts:
// https://wiki.shibboleth.net/confluence/display/CONCEPT/MetadataForSP
const SP_SIDE_ASSERTION_CONSUME_SERVICE_ENDPOINT = "/samlsp/assertionconsumeserviceendpoint";
const SP_SIDE_SINGLE_LOGOUT_SERVICE_ENDPOINT = "/samlsp/singlelogoutserviceendpoint"

// term login initiator is borrowed from Shibboleth SP so that those who are
// more familiar with Shibboleth SP understand this endpoints role
const SP_LOGIN_INITIATOR = "/logininitiator";


const SECURED_CONTENT_ENDPOINT = "/secured";
const IDP_ENTRY_POINT_URL = "https://" + IDENTITY_PROVIDER_DOMAIN + "/idp";
const IDP_ISSUER = "idp-issuer";
const AUDIENCE = "https://" + SAML_SP_DOMAIN + "/samlsp";
const SP_ASSERTION_CONSUME_SERVICE_URL = "https://" + SAML_SP_DOMAIN + SP_SIDE_ASSERTION_CONSUME_SERVICE_ENDPOINT;
const SP_SINGLE_LOGOUT_SERVICE_URL = "https://" + SAML_SP_DOMAIN + SP_SIDE_SINGLE_LOGOUT_SERVICE_ENDPOINT;
const IDP_CERT = fs.readFileSync(__dirname + '/static/cert.pem');
const IDP_KEY = fs.readFileSync(__dirname + '/static/key.pem');


describe("IdP initiated SLO must work without cookies", function() {
    it("reference case (with appliaction's session mgmt cookie available during LogoutRequest handling)", async function() {
        // make it easier to spend some time
        // at debug breakpoints
        this.timeout(999999999);

        const {app, sessionstore} = initializeSAMLSPApp();

        const agent = supertest.agent(app);
        // Host is masked to following value to
        // "document" requests which are made to saml sp
        // in a produced debug log
        agent.set("Host", SAML_SP_DOMAIN);

        // check that secured content cannot be accessed prior
        // to authenctication
        let res = await agent.get(SECURED_CONTENT_ENDPOINT);
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(403);

        // initiate login process
        res = await agent.get(SP_LOGIN_INITIATOR)
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(302);
        expect(res.header.location).to.startWith(IDP_ENTRY_POINT_URL + "?SAMLRequest=");

        const NAME_ID = "aaaaaaaaa@aaaaaaaa.local";
        const SESSION_INDEX = "_1111111111111111111111";
        const inResponseTo = "firstAuthnRequest";

        // end user has been authenticate at IdP and is forwarded back to SP
        res = await agent.post(SP_SIDE_ASSERTION_CONSUME_SERVICE_ENDPOINT)
            .send("SAMLResponse=" + encodeURIComponent(buildLoginResponse(NAME_ID, SESSION_INDEX, inResponseTo)));
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(302);

        // he/she can now access following content
        res = await agent.get(SECURED_CONTENT_ENDPOINT);
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(200);
        expect(res.text).to.contain(NAME_ID);

        //
        // Now end user decides to use other services which participate to same IdP SSO.
        //
        // Time goes by and finally end user decides to trigger SLO process.
        // SLO is initiated from some random SAML SP enabled service. From
        // this case point of view it is important to keep in mind that this
        // passport-saml instance didn't trigger it.
        //
        // If IdP is Shibboleth IdPv3 end user ends up to this process
        // https://wiki.shibboleth.net/confluence/display/IDP30/LogoutConfiguration#LogoutConfiguration-Overview
        // "....user chooses SLO, the logout-propagate.vm view is rendered and the browser mediates (i.e. front-channel)
        // a series of logout messages coordinated via iframes, javascript...".
        //
        // Links to actual implementation:
        // https://git.shibboleth.net/view/?p=java-identity-provider.git;a=blob;f=idp-conf/src/main/resources/views/logout-propagate.vm;h=86b3fa14d650073428c3688aabddee6f5f49bb47;hb=refs/heads/maint-3.4
        // https://git.shibboleth.net/view/?p=java-identity-provider.git;a=blob;f=idp-conf/src/main/resources/system/views/logout/propagate.vm;h=8a71905a5831714cb0a317321c5a72524922130f;hb=refs/heads/maint-3.4
        //
        // Following http request is executed from a browser which is currently rendering
        // logout-propage page at IdP site:
        await callSLOEndpointAndAssertResult(sessionstore, agent, NAME_ID, SESSION_INDEX);

        // Logout propagation page at IdP site has switched status of "passport-saml site" to indicate that
        // user was successfully logged out (because passport-saml returned LogoutResponse with status Success).
        //
        // End user walks away from computer thinking that he/she does not have any open login sessions
        // anymore.
        //
        // After few moments user or someone with the access to computer writes to browser's
        // address bar following address which must not be available without authentication
        // (remember that moments ago IdP indicated that all sessions were terminated)
        //
        // access to secured content must not work
        res = await agent.get(SECURED_CONTENT_ENDPOINT);
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(403);

        // Everything worked (access was blocked) as expected (in this case).
        // Move on to the next case...

    });

    it("IdP initiated LogoutRequest must work without additional information from e.g. cookies", async function() {

        // this is similar case than "reference case" until IdP-initiated LogoutRequest is sent
        // from browser.
        //
        // In this case end user has configured his/her browser to block third party cookies.
        //
        // NOTE: chrome is planning to block third party cookies by default so this scenario
        // is going to be very common.
        //
        //
        this.timeout(999999999);
        const {app, sessionstore} = initializeSAMLSPApp();
        const agent = supertest.agent(app);
        agent.set("Host", SAML_SP_DOMAIN);
        let res = await agent.get(SECURED_CONTENT_ENDPOINT);
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(403);
        res = await agent.get(SP_LOGIN_INITIATOR)
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(302);
        expect(res.header.location).to.startWith(IDP_ENTRY_POINT_URL + "?SAMLRequest=");

        const NAME_ID = "bbbbbbbbbbbbbbb@bbbbbbbbbbb.local";
        const SESSION_INDEX = "_222222222222222222222222";
        const inResponseTo = "secondAuthnRequest";

        res = await agent.post(SP_SIDE_ASSERTION_CONSUME_SERVICE_ENDPOINT)
            .send("SAMLResponse=" + encodeURIComponent(buildLoginResponse(NAME_ID, SESSION_INDEX, inResponseTo)));
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(302);

        // he/she can now access following content
        res = await agent.get(SECURED_CONTENT_ENDPOINT);
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(200);
        expect(res.text).to.contain(NAME_ID);

        // Proceeding to SLO...
        //
        // This is similar situation with "reference case" but because third party cookies are blocked
        // by end user's browser following request is executed without express-session's session cookie.
        // HTTP calls from within iframe do not contain cookies when third party cookies are blocked.
        //
        // This situation is simulated by this demonstration code so that superagent's cookiejar is cleared
        // prior to following HTTP call.
        //
        // store current cookies so that these can be restored
        const cookies = agent.jar.getCookies(cookiejar.CookieAccessInfo.All);
        //console.log("cookies\n:" + cookies);
        // clear cookie jar by expiring each cookie (cookiejar doesn't provide clear all or similar function)
        cookies.forEach(function(cookie) {
            const modifiedExpiration = new cookiejar.Cookie("" + cookie);
            modifiedExpiration.expiration_date = 0;
            agent.jar.setCookie(modifiedExpiration);
        });
        // execute same IdP-initiated logout request as in "reference case"
        await callSLOEndpointAndAssertResult(sessionstore, agent, NAME_ID, SESSION_INDEX);
        // restore cookiejar content. NOTE: this is not something that end user would
        // have to do in order to replicate this issue. His/her browser remembers cookies and
        // uses thosee when he/she navigates back to site via bookmark or via some weblink.
        agent.jar.setCookies(cookies);

        // passport-saml returned logout response with Success.
        // This means that passport-saml was able to logout user successfully using information
        // in logout request (nameId and sessionIndex) or passport-saml failed and reported
        // Success anyway.
        //
        // Eitherway:
        // Logout propagation page at IdP site has switched status of "passport-saml site" to indicate that
        // user was successfully logged out (because passport-saml returned LogoutResponse with status Success).
        //
        // End user walks away from computer thinking that he/she does not have any open login sessions
        // anymore.
        //
        // After few moments user or someone with the access to computer writes to browser's
        // address bar following address which must not be available without authentication
        // (remember that moments ago IdP indicated that all sessions were terminated)
        //
        // access to secured content must not work
        res = await agent.get(SECURED_CONTENT_ENDPOINT);
        logRequestResponse(sessionstore, res);
        expect(res.statusCode).to.equal(403);

        // this case failed (content was returned)...what went wrong?
        //
        // This didn't work during LogoutRequest handling:
        // req.logout()
        // https://github.com/bergie/passport-saml/blob/v1.2.0/lib/passport-saml/strategy.js#L46
        // It was executed without checking if session is same as
        // SAML logout request indicated with nameId and sessionIndex values.
        //
        // It was not checked if req contains authenticated session in the first place.
        //
        // LogoutRequest processing returns always Success if request's signature is valid. There
        // aren't any additional verifications whether correct session (or session at all) is
        // terminated when LogoutRequest was handled.
    });
});

async function callSLOEndpointAndAssertResult(sessionstore, agent, nameId, sessionIndex) {
    const idpInitiatedLogoutRequest = buildIdPInitiatedLogoutRequest(nameId, sessionIndex);
    const urlEncodedLogoutRequest = "SAMLRequest=" + encodeURIComponent(idpInitiatedLogoutRequest);
    const res = await agent.post(SP_SIDE_SINGLE_LOGOUT_SERVICE_ENDPOINT).send(urlEncodedLogoutRequest);
    logRequestResponse(sessionstore, res,
        urlEncodedLogoutRequest + "\n\nSAML request as decoded:\n" + Buffer.from(idpInitiatedLogoutRequest, "base64"));
    // Check that logout response is: "session designated by nameId&sessionIndex is terminated successfully"
    expect(res.statusCode).to.equal(302);
    expect(res.header.location).to.startWith(IDP_ENTRY_POINT_URL + "?SAMLResponse=");
    const logoutResponse = getSamlMessageFromRedirectResponse(res);
    const logoutResponseJson = await xml2js.parseStringPromise(logoutResponse);
    // console.log("XML\n" + logoutResponse + "\nXML2JS:\n" + JSON.stringify( logoutResponseJson, null, 2));
    expect(logoutResponseJson["samlp:LogoutResponse"]["samlp:Status"][0]["samlp:StatusCode"][0]['$'].Value)
        .to
        .equal("urn:oasis:names:tc:SAML:2.0:status:Success")
}

function initializeSAMLSPApp() {
    const app = express();
    const memoryStoreInstance = new memorystore({checkPeriod: 86400000});
    app.use(bodyParser.urlencoded({encoded: true}));
    app.use(session({
        // this is false so that session is written to memory store
        // when it is authenticated. Makes it easier to demonstrate
        // passport-saml SLO issue.
        saveUninitialized: false,
        secret: "secret_used_to_sign_cookie",
        store: memoryStoreInstance
    }));
    app.use(passport.initialize());
    app.use(passport.session());
    passport.serializeUser( function(user, done) { done(null, user); } );
    passport.deserializeUser( function(user, done) { done(null, user); } );
    passport.use(new SamlStrategy({
        callbackUrl: SP_ASSERTION_CONSUME_SERVICE_URL,
        entryPoint: IDP_ENTRY_POINT_URL,
        issuer: "passport-saml-issuer",
        // in response to validation disabled
        // because it is irrelevant from SLO logout issue
        // demonstration case point of view
        validateInResponseTo: false,
        cert: IDP_CERT.toString(),
        acceptedClockSkewMs: 0,
        idpIssuer: IDP_ISSUER,
        audience: AUDIENCE,
    }, function(profile, done) { done(null, profile) }));
    app.get(SP_LOGIN_INITIATOR, passport.authenticate("saml", {} ));
    app.post(SP_SIDE_ASSERTION_CONSUME_SERVICE_ENDPOINT, passport.authenticate("saml", {} ), function(req, res){res.redirect("/")});
    app.post(SP_SIDE_SINGLE_LOGOUT_SERVICE_ENDPOINT, passport.authenticate("saml", {} ));
    // this endpoint is used to test whether user has authenticated session or not
    app.get(SECURED_CONTENT_ENDPOINT, function(req, res) {
        if (req.isAuthenticated()) {
            res.send("hello " + req.user.nameID);
        } else {
            res.sendStatus(403);
        }
    });

    return {
        app: app,
        sessionstore: memoryStoreInstance.store
    }
}

function buildIdPInitiatedLogoutRequest(nameId, sessionIndex) {
    // const nameId = "asdf@qwerty.local";
    // const sessionIndex = "_ababababababababababab";
    const issuer = IDP_ISSUER;
    const spNameQualifier = AUDIENCE;
    const destination = SP_SINGLE_LOGOUT_SERVICE_URL;

    const idpInitiatedLogoutRequest =
`<samlp:LogoutRequest
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="_adcdabcd"
    Version="2.0"
    IssueInstant="2020-01-01T01:01:00Z"
    Destination="${destination}">
    <saml:Issuer>${issuer}</saml:Issuer>
    <saml:NameID
        SPNameQualifier="${spNameQualifier}"
        Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">${nameId}</saml:NameID>
    <samlp:SessionIndex>${sessionIndex}</samlp:SessionIndex>
</samlp:LogoutRequest>`
    return Buffer.from(signXml(idpInitiatedLogoutRequest)).toString("base64");
}

function buildLoginResponse(nameId, sessionIndex, inResponseTo) {
    // const nameId = "asdf@qwerty.local";
    // const inResponseTo = "_ccccccccccccc";
    // const sessionIndex = "_ababababababababababab";
    const notBefore = "1980-01-01T01:00:00Z"
    const issueInstant = "1980-01-01T01:01:00Z";
    const notOnOrAfter = "4980-01-01T01:01:00Z";
    const issuer = IDP_ISSUER;
    const audience = AUDIENCE;
    const destination = SP_ASSERTION_CONSUME_SERVICE_URL;

    const loginResponse =
`<samlp:Response
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    Version="2.0"
    IssueInstant="${issueInstant}"
    Destination="${destination}"
    InResponseTo="${inResponseTo}">
    <saml:Issuer>${issuer}</saml:Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        ID="_bbbbbbbbbbbbbbbbbbbbbbbb"
        Version="2.0" IssueInstant="${issueInstant}">
        <saml:Issuer>${issuer}</saml:Issuer>
        <saml:Subject>
            <saml:NameID
                SPNameQualifier="${audience}"
                Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">${nameId}</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml:SubjectConfirmationData
                    NotOnOrAfter="${notOnOrAfter}"
                    Recipient="${destination}"
                    InResponseTo="${inResponseTo}"/>
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions
            NotBefore="${notBefore}"
            NotOnOrAfter="${notOnOrAfter}">
            <saml:AudienceRestriction>
                <saml:Audience>${audience}</saml:Audience>
            </saml:AudienceRestriction>
        </saml:Conditions>
       <saml:AuthnStatement
            AuthnInstant="${issueInstant}"
            SessionNotOnOrAfter="${notOnOrAfter}"
            SessionIndex="${sessionIndex}">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
    </saml:Assertion>
</samlp:Response>`
    return Buffer.from(signXml(loginResponse)).toString("base64");
}

function signXml(xml) {
    const sig = new SignedXml();
    sig.addReference('/*',
        ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"],
        "http://www.w3.org/2001/04/xmlenc#sha256", "", "", "", false
    );
    sig.signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
    sig.signingKey = IDP_KEY;
    sig.computeSignature(xml);
    return sig.getSignedXml();
}

function logRequestResponse(sessionstore, res, requestBody) {
    let msg = "---- BEGIN ----------------------------------------------------------------\n";
    msg += "HTTP REQUEST:\n";
    msg += res.req._header + (requestBody ? requestBody : "");
    msg += "\n\nHTTP RESPONSE:\n";
    msg += "HTTP/" + res.res.httpVersion + " " + res.statusCode + " " + res.res.statusMessage + "\n";
    Object.keys(res.header).forEach(function (header) {msg += header + ": " + res.header[header] + "\n"});
    msg += "\n";
    msg += res.text ? res.text : "";

    let xml = getSamlMessageFromRedirectResponse(res);
    if (xml) {
        msg += "\n\n-------\n";
        msg += "HTTP redirect response's saml message decoded:\n" + xml + "\n";
    }
    msg += "\n\n-------\n";
    msg += "Content of session store per sessionId AFTER the request has been processed:\n";
    sessionstore.keys().forEach(function(sid) {
        msg += "content of " + sid + " :\n" + JSON.stringify(JSON.parse(sessionstore.get(sid)), null, 2) + "\n"
    });
    msg += "\n---- END -------------------------------------------------------------------\n";
    console.log(msg);
}

function getSamlMessageFromRedirectResponse(res) {
    if (res.header && res.header.location) {
        const location = url.parse(res.header.location, true);
        if (location.query['SAMLRequest']) {
            return decodeXmlMessage(location.query['SAMLRequest']);
        } else
        if (location.query['SAMLResponse']) {
            return decodeXmlMessage(location.query['SAMLResponse']);
        }
    }
}

function decodeXmlMessage(msg) {
    const decoded = Buffer.from(msg, "base64");
    const inflated = Buffer.from(zlib.inflateRawSync(decoded), "utf-8");
    return new xmldom.DOMParser({}).parseFromString(inflated.toString());
}

Output of reference case (with appliaction's session mgmt cookie available during LogoutRequest handling)


... logs after SAML login is completed .....

---- BEGIN ----------------------------------------------------------------
HTTP REQUEST:
GET /secured HTTP/1.1
Host: passport-saml-powered-SAML-SP.qwerty.local
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.8.3
Cookie: connect.sid=s%3AwKYuE4TZyfzrUBP8yLJHYy53n4KlxC0s.DUFFvSzgv%2BKT3pjUb7O7jnh%2BlVB7o2pjAvDoixhz5%2FE
Connection: close



HTTP RESPONSE:
HTTP/1.1 200 OK
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 30
etag: W/"1e-pkiapmYFJr5Z2ZLWfKJs1kp+5k4"
date: Sun, 02 Feb 2020 17:17:07 GMT
connection: close

hello aaaaaaaaa@aaaaaaaa.local

-------
Content of session store per sessionId AFTER the request has been processed:
content of wKYuE4TZyfzrUBP8yLJHYy53n4KlxC0s :
{
  "cookie": {
    "originalMaxAge": null,
    "expires": null,
    "httpOnly": true,
    "path": "/"
  },
  "passport": {
    "user": {
      "issuer": "idp-issuer",
      "inResponseTo": "firstAuthnRequest",
      "sessionIndex": "_1111111111111111111111",
      "nameID": "aaaaaaaaa@aaaaaaaa.local",
      "nameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
      "spNameQualifier": "https://passport-saml-powered-SAML-SP.qwerty.local/samlsp"
    }
  }
}

---- END -------------------------------------------------------------------


---- BEGIN ----------------------------------------------------------------
HTTP REQUEST:
POST /samlsp/singlelogoutserviceendpoint HTTP/1.1
Host: passport-saml-powered-SAML-SP.qwerty.local
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.8.3
Content-Type: application/x-www-form-urlencoded
Cookie: connect.sid=s%3AwKYuE4TZyfzrUBP8yLJHYy53n4KlxC0s.DUFFvSzgv%2BKT3pjUb7O7jnh%2BlVB7o2pjAvDoixhz5%2FE
Content-Length: 2150
Connection: close

SAMLRequest=PHNhbWxwOkxvZ291dFJlcXVlc3QgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il9hZGNkYWJjZCIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDEtMDFUMDE6MDE6MDBaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9wYXNzcG9ydC1zYW1sLXBvd2VyZWQtU0FNTC1TUC5xd2VydHkubG9jYWwvc2FtbHNwL3NpbmdsZWxvZ291dHNlcnZpY2VlbmRwb2ludCI%2BCiAgICA8c2FtbDpJc3N1ZXI%2BaWRwLWlzc3Vlcjwvc2FtbDpJc3N1ZXI%2BCiAgICA8c2FtbDpOYW1lSUQgU1BOYW1lUXVhbGlmaWVyPSJodHRwczovL3Bhc3Nwb3J0LXNhbWwtcG93ZXJlZC1TQU1MLVNQLnF3ZXJ0eS5sb2NhbC9zYW1sc3AiIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50Ij5hYWFhYWFhYWFAYWFhYWFhYWEubG9jYWw8L3NhbWw6TmFtZUlEPgogICAgPHNhbWxwOlNlc3Npb25JbmRleD5fMTExMTExMTExMTExMTExMTExMTExMTwvc2FtbHA6U2Vzc2lvbkluZGV4Pgo8U2lnbmF0dXJlIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48U2lnbmVkSW5mbz48Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjxTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Ii8%2BPFJlZmVyZW5jZSBVUkk9IiNfYWRjZGFiY2QiPjxUcmFuc2Zvcm1zPjxUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L1RyYW5zZm9ybXM%2BPERpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxEaWdlc3RWYWx1ZT50RlF1V0luWjJMV1NiQ2lFeE1IeXg0WjhuUVRrbmxabEtVZE1qeVY0WUw0PTwvRGlnZXN0VmFsdWU%2BPC9SZWZlcmVuY2U%2BPC9TaWduZWRJbmZvPjxTaWduYXR1cmVWYWx1ZT5nUHRQcDM3T29YN0MyUEMvdmpGRlViUnF4NVRUNnZ6UkJxYk1XWHdDTmxsOHIrOE8wblJUMHNRcHpxaDlUbk5CTTlBejBYdjhpSkFCMTNBWHQvWGNFY3NBTSswZEdFRmd5dlZHV25hdTFHd3h0MjV5Nm1Bblo5NVhIK2txUHNUZTJaRHVzK3k4aWtZL1drY0FIZ1lGOEFJb1dWY2VsdmNUalhQSk5zYTJOMllDdUtVZXBMMVlBRmcxM2x6NnhHNjJMUEtlV2Frd0M2VlBMQ2FlWVpwaVpucElXWENWVkR6NFByL1FUZWpsSng2NFJ1eGthYXBQK3JZMkpwaTVmL0VNNStYTmJQQlVOT2xnTFdxalI3YkFxekpXQ2pVZHBvbndxVjBCMTBOeFdTZGQ3aEk4eXhaODllODZjcEhuYjZoMWM2WGExZmk1MFp3T29rMGkwN0tja0E9PTwvU2lnbmF0dXJlVmFsdWU%2BPC9TaWduYXR1cmU%2BPC9zYW1scDpMb2dvdXRSZXF1ZXN0Pg%3D%3D

SAML request as decoded:
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_adcdabcd" Version="2.0" IssueInstant="2020-01-01T01:01:00Z" Destination="https://passport-saml-powered-SAML-SP.qwerty.local/samlsp/singlelogoutserviceendpoint">
    <saml:Issuer>idp-issuer</saml:Issuer>
    <saml:NameID SPNameQualifier="https://passport-saml-powered-SAML-SP.qwerty.local/samlsp" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">aaaaaaaaa@aaaaaaaa.local</saml:NameID>
    <samlp:SessionIndex>_1111111111111111111111</samlp:SessionIndex>
<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/2001/04/xmldsig-more#rsa-sha256"/><Reference URI="#_adcdabcd"><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/2001/04/xmlenc#sha256"/><DigestValue>tFQuWInZ2LWSbCiExMHyx4Z8nQTknlZlKUdMjyV4YL4=</DigestValue></Reference></SignedInfo><SignatureValue>gPtPp37OoX7C2PC/vjFFUbRqx5TT6vzRBqbMWXwCNll8r+8O0nRT0sQpzqh9TnNBM9Az0Xv8iJAB13AXt/XcEcsAM+0dGEFgyvVGWnau1Gwxt25y6mAnZ95XH+kqPsTe2ZDus+y8ikY/WkcAHgYF8AIoWVcelvcTjXPJNsa2N2YCuKUepL1YAFg13lz6xG62LPKeWakwC6VPLCaeYZpiZnpIWXCVVDz4Pr/QTejlJx64RuxkaapP+rY2Jpi5f/EM5+XNbPBUNOlgLWqjR7bAqzJWCjUdponwqV0B10NxWSdd7hI8yxZ89e86cpHnb6h1c6Xa1fi50ZwOok0i07KckA==</SignatureValue></Signature></samlp:LogoutRequest>

HTTP RESPONSE:
HTTP/1.1 302 Found
x-powered-by: Express
location: https://identity-provider.asdf.local/idp?SAMLResponse=fVFNa8MwDP0rwfd8NDTpMG3KWC%2BF7rKWHnYZqq12gcQ2llK2fz8tXVkHo6CLnt6Tnp%2Fny4%2B%2BS84YqfVuoSZZoZbNnKDvgt74kx%2F4BSl4R5gI0ZEeRws1RKc9UEvaQY%2Bk2ejt4%2FNGl1mhQ%2FTsje%2FUjeS%2BAogwsjhQyXq1UG%2BHCqaItq7K49TUMHmYTY1K9leXIhEi0YBrRwyOBSrKIi1Kqd1kpqWKWVZX9atKVkjcOuBR%2Bc4cSOd5a9Fxy5%2BpeD1LEzMge8w6b6CTYZD17vrwnRdHYI2Fg7HqEo4er8cmiPPgI6ffYNqO4Dy%2FZfxkuWXggf52T95isoduwPvp0MjW28EYJFJ5c7nwuzT%2F77%2BaLw%3D%3D
content-length: 0
date: Sun, 02 Feb 2020 17:17:07 GMT
connection: close



-------
HTTP redirect response's saml message decoded:
<?xml version="1.0"?><samlp:LogoutResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_b5a4eed652f4c6a1874c" Version="2.0" IssueInstant="2020-02-02T17:17:07.656Z" Destination="https://identity-provider.asdf.local/idp" InResponseTo="_adcdabcd"><saml:Issuer>passport-saml-issuer</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status></samlp:LogoutResponse>


-------
Content of session store per sessionId AFTER the request has been processed:
content of wKYuE4TZyfzrUBP8yLJHYy53n4KlxC0s :
{
  "cookie": {
    "originalMaxAge": null,
    "expires": null,
    "httpOnly": true,
    "path": "/"
  },
  "passport": {}
}

---- END -------------------------------------------------------------------


---- BEGIN ----------------------------------------------------------------
HTTP REQUEST:
GET /secured HTTP/1.1
Host: passport-saml-powered-SAML-SP.qwerty.local
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.8.3
Cookie: connect.sid=s%3AwKYuE4TZyfzrUBP8yLJHYy53n4KlxC0s.DUFFvSzgv%2BKT3pjUb7O7jnh%2BlVB7o2pjAvDoixhz5%2FE
Connection: close



HTTP RESPONSE:
HTTP/1.1 403 Forbidden
x-powered-by: Express
content-type: text/plain; charset=utf-8
content-length: 9
etag: W/"9-PatfYBLj4Um1qTm5zrukoLhNyPU"
date: Sun, 02 Feb 2020 17:17:07 GMT
connection: close

Forbidden

-------
Content of session store per sessionId AFTER the request has been processed:
content of wKYuE4TZyfzrUBP8yLJHYy53n4KlxC0s :
{
  "cookie": {
    "originalMaxAge": null,
    "expires": null,
    "httpOnly": true,
    "path": "/"
  },
  "passport": {}
}

---- END -------------------------------------------------------------------

Output of IdP initiated LogoutRequest must work without additional information from e.g. cookies


... logs after SAML login is completed .....


---- BEGIN ----------------------------------------------------------------
HTTP REQUEST:
GET /secured HTTP/1.1
Host: passport-saml-powered-SAML-SP.qwerty.local
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.8.3
Cookie: connect.sid=s%3A-9Ii5aSBusDH0PO7Ec3qaEhJ1io7zyCa.rf3kRGWh6%2FDNURxdpRfiKk%2FTpL%2FIsje3byfPjDphkNg
Connection: close



HTTP RESPONSE:
HTTP/1.1 200 OK
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 39
etag: W/"27-78k8vTxTl1L2wj/JDDGs3fBzmvk"
date: Sun, 02 Feb 2020 17:21:50 GMT
connection: close

hello bbbbbbbbbbbbbbb@bbbbbbbbbbb.local

-------
Content of session store per sessionId AFTER the request has been processed:
content of -9Ii5aSBusDH0PO7Ec3qaEhJ1io7zyCa :
{
  "cookie": {
    "originalMaxAge": null,
    "expires": null,
    "httpOnly": true,
    "path": "/"
  },
  "passport": {
    "user": {
      "issuer": "idp-issuer",
      "inResponseTo": "secondAuthnRequest",
      "sessionIndex": "_222222222222222222222222",
      "nameID": "bbbbbbbbbbbbbbb@bbbbbbbbbbb.local",
      "nameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
      "spNameQualifier": "https://passport-saml-powered-SAML-SP.qwerty.local/samlsp"
    }
  }
}

---- END -------------------------------------------------------------------


---- BEGIN ----------------------------------------------------------------
HTTP REQUEST:
POST /samlsp/singlelogoutserviceendpoint HTTP/1.1
Host: passport-saml-powered-SAML-SP.qwerty.local
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.8.3
Content-Type: application/x-www-form-urlencoded
Content-Length: 2162
Connection: close

SAMLRequest=PHNhbWxwOkxvZ291dFJlcXVlc3QgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il9hZGNkYWJjZCIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMjAtMDEtMDFUMDE6MDE6MDBaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9wYXNzcG9ydC1zYW1sLXBvd2VyZWQtU0FNTC1TUC5xd2VydHkubG9jYWwvc2FtbHNwL3NpbmdsZWxvZ291dHNlcnZpY2VlbmRwb2ludCI%2BCiAgICA8c2FtbDpJc3N1ZXI%2BaWRwLWlzc3Vlcjwvc2FtbDpJc3N1ZXI%2BCiAgICA8c2FtbDpOYW1lSUQgU1BOYW1lUXVhbGlmaWVyPSJodHRwczovL3Bhc3Nwb3J0LXNhbWwtcG93ZXJlZC1TQU1MLVNQLnF3ZXJ0eS5sb2NhbC9zYW1sc3AiIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50Ij5iYmJiYmJiYmJiYmJiYmJAYmJiYmJiYmJiYmIubG9jYWw8L3NhbWw6TmFtZUlEPgogICAgPHNhbWxwOlNlc3Npb25JbmRleD5fMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyPC9zYW1scDpTZXNzaW9uSW5kZXg%2BCjxTaWduYXR1cmUgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxTaWduZWRJbmZvPjxDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8%2BPFNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48UmVmZXJlbmNlIFVSST0iI19hZGNkYWJjZCI%2BPFRyYW5zZm9ybXM%2BPFRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8%2BPFRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvVHJhbnNmb3Jtcz48RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8%2BPERpZ2VzdFZhbHVlPlRFeExvVGRYS3Q0dEtQK0l3cTU4OHlGbnF2VnVvNDVHOUo3T2E3SkZiUjA9PC9EaWdlc3RWYWx1ZT48L1JlZmVyZW5jZT48L1NpZ25lZEluZm8%2BPFNpZ25hdHVyZVZhbHVlPmFGM3YvZkNwWE5HdXJiTkZDUm1XVVZzcDhleEpKRFdYNkZGRXZ1bkVGcFhIQlFiZDdMR3VqQnNIMEZ3Z2Y2SUd2dncxeDArS2pwZnBLTTZLK2pzUGVTUTVSSVJSeTJKM3dlbENKMlhxUStMRjMyR2ZoWW9tM3ZYRm1lL2t2ajdlemdpVHEzV0dUNTQzS0FPWDNjMnArbk1yUkJQL1VBT3EyQm9iNUZXREhPbFluOXFEelZSc3p2VUkvQWZkOTNrSkV4N2tHV1hKdlFCalVhbUxOd1RrbW0wUmlGSHJQblg0cDV1U2xzT3ZBUTJ1UVhyclUxOUR2UE0zUWczTlVJMnorOW5xWWY0NWxJR05NamVkOFFqVXFqNG8yYm1wYTFPQkpIMitjK01tVW9nVXdsbC9idlNac21aa2haMEZybXRhTEJiT0hYWGhkYjBHMmNwOGFuQjlWdz09PC9TaWduYXR1cmVWYWx1ZT48L1NpZ25hdHVyZT48L3NhbWxwOkxvZ291dFJlcXVlc3Q%2B

SAML request as decoded:
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_adcdabcd" Version="2.0" IssueInstant="2020-01-01T01:01:00Z" Destination="https://passport-saml-powered-SAML-SP.qwerty.local/samlsp/singlelogoutserviceendpoint">
    <saml:Issuer>idp-issuer</saml:Issuer>
    <saml:NameID SPNameQualifier="https://passport-saml-powered-SAML-SP.qwerty.local/samlsp" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">bbbbbbbbbbbbbbb@bbbbbbbbbbb.local</saml:NameID>
    <samlp:SessionIndex>_222222222222222222222222</samlp:SessionIndex>
<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/2001/04/xmldsig-more#rsa-sha256"/><Reference URI="#_adcdabcd"><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/2001/04/xmlenc#sha256"/><DigestValue>TExLoTdXKt4tKP+Iwq588yFnqvVuo45G9J7Oa7JFbR0=</DigestValue></Reference></SignedInfo><SignatureValue>aF3v/fCpXNGurbNFCRmWUVsp8exJJDWX6FFEvunEFpXHBQbd7LGujBsH0Fwgf6IGvvw1x0+KjpfpKM6K+jsPeSQ5RIRRy2J3welCJ2XqQ+LF32GfhYom3vXFme/kvj7ezgiTq3WGT543KAOX3c2p+nMrRBP/UAOq2Bob5FWDHOlYn9qDzVRszvUI/Afd93kJEx7kGWXJvQBjUamLNwTkmm0RiFHrPnX4p5uSlsOvAQ2uQXrrU19DvPM3Qg3NUI2z+9nqYf45lIGNMjed8QjUqj4o2bmpa1OBJH2+c+MmUogUwll/bvSZsmZkhZ0FrmtaLBbOHXXhdb0G2cp8anB9Vw==</SignatureValue></Signature></samlp:LogoutRequest>

HTTP RESPONSE:
HTTP/1.1 302 Found
x-powered-by: Express
location: https://identity-provider.asdf.local/idp?SAMLResponse=fVHBbsIwDP2VKve2abcysKBoGhckdhmIwy6TSc1WqSRR7KLt75eVoTEJIeXi5%2Ffs55fp%2FPPQJUcK3Do7U0Wm1byeMh46Dyv37np5IfbOMiWRaBmG1kz1wYJDbhksHohBDKwfn1dQZhp8cOKM69SF5LYCmSlIdKCS5WKm3mhfaJqM72hU4ei%2B2lVYjVWyPbuMkkhk7mlpWdBKhHSpU13GtykeoCyg0tmkGL2qZEEsrUUZlB8iniHP24astPKVRq%2FHWIQMudlnnTPYxaaP4%2B358I2LjrAxDe5Mo07hwLA91D469y5I%2BgOm7QBO80vGb5ZrQen5f%2FXkGkq22PV0Ox0e2LDujSFmldenDX9D82v%2FVX8D
content-length: 0
date: Sun, 02 Feb 2020 17:21:50 GMT
connection: close



-------
HTTP redirect response's saml message decoded:
<?xml version="1.0"?><samlp:LogoutResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_ef10e983e65a645b5a58" Version="2.0" IssueInstant="2020-02-02T17:21:50.916Z" Destination="https://identity-provider.asdf.local/idp" InResponseTo="_adcdabcd"><saml:Issuer>passport-saml-issuer</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status></samlp:LogoutResponse>


-------
Content of session store per sessionId AFTER the request has been processed:
content of -9Ii5aSBusDH0PO7Ec3qaEhJ1io7zyCa :
{
  "cookie": {
    "originalMaxAge": null,
    "expires": null,
    "httpOnly": true,
    "path": "/"
  },
  "passport": {
    "user": {
      "issuer": "idp-issuer",
      "inResponseTo": "secondAuthnRequest",
      "sessionIndex": "_222222222222222222222222",
      "nameID": "bbbbbbbbbbbbbbb@bbbbbbbbbbb.local",
      "nameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
      "spNameQualifier": "https://passport-saml-powered-SAML-SP.qwerty.local/samlsp"
    }
  }
}

---- END -------------------------------------------------------------------


---- BEGIN ----------------------------------------------------------------
HTTP REQUEST:
GET /secured HTTP/1.1
Host: passport-saml-powered-SAML-SP.qwerty.local
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.8.3
Cookie: connect.sid=s%3A-9Ii5aSBusDH0PO7Ec3qaEhJ1io7zyCa.rf3kRGWh6%2FDNURxdpRfiKk%2FTpL%2FIsje3byfPjDphkNg
Connection: close



HTTP RESPONSE:
HTTP/1.1 200 OK
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 39
etag: W/"27-78k8vTxTl1L2wj/JDDGs3fBzmvk"
date: Sun, 02 Feb 2020 17:21:50 GMT
connection: close

hello bbbbbbbbbbbbbbb@bbbbbbbbbbb.local

-------
Content of session store per sessionId AFTER the request has been processed:
content of -9Ii5aSBusDH0PO7Ec3qaEhJ1io7zyCa :
{
  "cookie": {
    "originalMaxAge": null,
    "expires": null,
    "httpOnly": true,
    "path": "/"
  },
  "passport": {
    "user": {
      "issuer": "idp-issuer",
      "inResponseTo": "secondAuthnRequest",
      "sessionIndex": "_222222222222222222222222",
      "nameID": "bbbbbbbbbbbbbbb@bbbbbbbbbbb.local",
      "nameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
      "spNameQualifier": "https://passport-saml-powered-SAML-SP.qwerty.local/samlsp"
    }
  }
}

---- END -------------------------------------------------------------------

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions