Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issuer is different in samlResponse for different IdP #283

Closed
suchitagarwal opened this issue May 23, 2018 · 15 comments
Closed

Issuer is different in samlResponse for different IdP #283

suchitagarwal opened this issue May 23, 2018 · 15 comments

Comments

@suchitagarwal
Copy link

Hi,
I am implementing SAML SSO using passport-saml. I want to be able to support all IdPs like GSuite, Okta, Onelogin, Auth0. I had been testing it with GSuite till now and everything works fine. However, when I tested with Okta, I noticed that there is a difference in the samlResponse that we get in the callback.

For GSuite, the samlResponse looks like:

{
  nameID: user@example.com,
  issuer: https://accounts.google.com/…,
  
}

for Okta, it looks like:

{
  nameID: user@example.com,
  issuer: {
    _: 'https://example.okta.com/oktaid/…',
    other data here…
  },
  
}

Effectively, the issuer is a string for GSuite samlResponse, while its an Object for an Okta samlResponse. Should this be handled by passport-saml itself, is this a known issue?

@a-legrand
Copy link

I agree, other fields are handled, for example profile.nameID = nameID[0]._ || nameID[0]; but not the Issuer

@cjbarth
Copy link
Collaborator

cjbarth commented Oct 2, 2018

@suchitagarwal @a-legrand , #187 seems to address this. There is a note on that PR asking for documentation before it gets landed. Do either of you have some documentation that could shed light on the standards compliance of this pattern?

@suchitagarwal
Copy link
Author

@cjbarth not off the top of my head, let me look around to see if i can find something

@markstos
Copy link
Contributor

markstos commented Jan 2, 2019

@mraible You work at Okta. Could you connect us with a SAML developer there who can shed light on why Okta returns their SAML responses in a different format than G-Suite? We want the passport-saml project to be spec-compliant, but also compatible with major providers like Okta. See ticket above for context. Thanks.

@jpf
Copy link

jpf commented Jan 8, 2019

Hey folks, I'm a co-worker of @mraible at Okta. Do you have some examples of the XML payloads that you're getting from the various IDPs?

Below is an example of what I'm looking for, it's a freshly minted and lightly anonymized SAML Response from one of my Okta orgs. To my eyes, the Issuer looks as it should be, but I'd like to compare this response with similar responses from other SAML IdPs:

<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                 Destination="https://example.okta.com/auth/saml20/jfranusic"
                 ID="id10703141429762751406940984"
                 IssueInstant="2019-01-08T19:04:37.100Z"
                 Version="2.0"
                 xmlns:xs="http://www.w3.org/2001/XMLSchema"
                 >
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                  Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
                  >http://www.okta.com/exk410hnrc2i3lsMb0h7</saml2: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="#id10703141429762751406940984">
                <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#">
                        <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
                                                PrefixList="xs"
                                                />
                    </ds:Transform>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>ikyWYyim/n6M0bVfCan8z7odOPYU52kgmmtfawuKmzA=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>hmpCHKGjrir8M8PBXyaNw8AGU4Mw1mNzyCKMVATel46Q34VXA310RsDNd1z1JS4QUIQo52k7zIWnzVp12s44xt88p1kCNNG8PtfZjwnb5kBCdxlCuXqU5iOLufsen3iJ/6s+Q7gQnyWdQf18igJzH5xpTfe8rnUkMllrkkh1BoTIhXBSHinS0Gr5kvGnn322UfP5dknPRJHf+bcu+w0I2yMb7BFza4a6/pDViVXocnTdvNJKXsQOTOEdf79h6gjqbyqC/9FhJddlxsNSZQLA0P5bBG7aq0kW6UkrSeRVOLUIT4Tv1OBBud/C6A9tCdgb0wUbhQoF8T7mX4/OxXogyg==</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>MIIDojCCAoqgAwIBAgIGAUsUC4wrMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWpmcmFudXNpYzEcMBoGCSqGSIb3DQEJARYN
aW5mb0Bva3RhLmNvbTAeFw0xNTAxMjIyMzQ2NTZaFw00NTAxMjIyMzQ3NTZaMIGRMQswCQYDVQQG
EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UE
CgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWpmcmFudXNpYzEcMBoGCSqG
SIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOc7
QmkAsgbYdbPLBBsGUwH4YlA1BeASfLyWsoCh4u2xiZ7Mn6VQ11LcHqmVwZbxNIgQsu08XXPR+jTQ
PGpv+jUNAGeWj9DS+6JrhXqIYNJ7wyiMj8asNY3NkWOrZfXjVwPJvVP10RgpNN6uegboKukhxvoG
mG84c491Ljkvlqbxa4Ez+gRP26kW2iolhI9uODHnFWj7QdK4CVQFJ9oXZv2WlEvtsthYkal5QJnS
RiADm2txYX6cF1YuRFYXLoIG3qgeQpt4lnttOBbI5vNo+50CSVmFOVxKHgRBkw2ovHsIIE+SSe3k
KSfDwMEaZvA7ig+sRx0+XVn8L1z+M5+MNIcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAjNzKq88V
hQGj5U6igE4h3b5VFF1a64tpQ6ZRxROuH/MT20iPWL9etRrrPAgQc3URvnQDNor1FWfIjsmUMEpF
BvpTAcKrJsVLcdmJZgcxaJjW9Umcvjuy5n8LAt00Dbgdy53dWXF1vUUICLXQUM9zm6nS39ziEI+8
y2RCcRiZAe2tIT4mmQs+g2SK0jyJRNYFkesdtd3yH83LC72uVtr4k/WEksswxsWGUSVh64j7OeEr
aZYO/MYofxNU8HhbfKDisDBAcvYAp6YZ9ee9eWyzwKi9Ho7wuRPBYuiBgjirTM2emw1HCv79uTUQ
SF6WWJ3D9YkwsHI4tFHODyyK46rd1Q==</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
    <saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
        <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
    </saml2p:Status>
    <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                     ID="id107031414298602791956523777"
                     IssueInstant="2019-01-08T19:04:37.100Z"
                     Version="2.0"
                     xmlns:xs="http://www.w3.org/2001/XMLSchema"
                     >
        <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
                      xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                      >http://www.okta.com/exk410hnrc2i3lsMb0h7</saml2: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="#id107031414298602791956523777">
                    <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#">
                            <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
                                                    PrefixList="xs"
                                                    />
                        </ds:Transform>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                    <ds:DigestValue>ZJwedjfR4lm3HwDWHN77amVKUw0groltiEh0sVc3b88=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>daXxf4ymjUngfnCXsNXBaTpSRe3qlbPexS9CPiuFT1m0CzRHFDX3ck/vgxJ/B1dEkXD1KcJ+U6xzTr1LQql/11K9ky1t4/GucnNEXxCZzKOb+7G6G+ctNkn6s2TKUHp83Cstw1JjRhTlge1kIYPHi9c/OpjeWTHiBcu2FMJszf5GPa6bwv4Eru7+QJtV9tvQ9z1n+YphuvL5vI0HChIOBYlTdRU9EB2Y+i8mLLk/oZ2GNV/vDG2sZ8eGxifxfAdBptOakZHk9WE4PbWHn2ZX+m9ql4WN2fYAilPzByiV+w+U7zVo3Yi4759fUaTlO1hu49Jn4XT3pDai2VQjW+znXg==</ds:SignatureValue>
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>MIIDojCCAoqgAwIBAgIGAUsUC4wrMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWpmcmFudXNpYzEcMBoGCSqGSIb3DQEJARYN
aW5mb0Bva3RhLmNvbTAeFw0xNTAxMjIyMzQ2NTZaFw00NTAxMjIyMzQ3NTZaMIGRMQswCQYDVQQG
EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UE
CgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWpmcmFudXNpYzEcMBoGCSqG
SIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOc7
QmkAsgbYdbPLBBsGUwH4YlA1BeASfLyWsoCh4u2xiZ7Mn6VQ11LcHqmVwZbxNIgQsu08XXPR+jTQ
PGpv+jUNAGeWj9DS+6JrhXqIYNJ7wyiMj8asNY3NkWOrZfXjVwPJvVP10RgpNN6uegboKukhxvoG
mG84c491Ljkvlqbxa4Ez+gRP26kW2iolhI9uODHnFWj7QdK4CVQFJ9oXZv2WlEvtsthYkal5QJnS
RiADm2txYX6cF1YuRFYXLoIG3qgeQpt4lnttOBbI5vNo+50CSVmFOVxKHgRBkw2ovHsIIE+SSe3k
KSfDwMEaZvA7ig+sRx0+XVn8L1z+M5+MNIcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAjNzKq88V
hQGj5U6igE4h3b5VFF1a64tpQ6ZRxROuH/MT20iPWL9etRrrPAgQc3URvnQDNor1FWfIjsmUMEpF
BvpTAcKrJsVLcdmJZgcxaJjW9Umcvjuy5n8LAt00Dbgdy53dWXF1vUUICLXQUM9zm6nS39ziEI+8
y2RCcRiZAe2tIT4mmQs+g2SK0jyJRNYFkesdtd3yH83LC72uVtr4k/WEksswxsWGUSVh64j7OeEr
aZYO/MYofxNU8HhbfKDisDBAcvYAp6YZ9ee9eWyzwKi9Ho7wuRPBYuiBgjirTM2emw1HCv79uTUQ
SF6WWJ3D9YkwsHI4tFHODyyK46rd1Q==</ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </ds:Signature>
        <saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
            <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">[email protected]</saml2:NameID>
            <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml2:SubjectConfirmationData NotOnOrAfter="2019-01-08T19:09:37.100Z"
                                               Recipient="https://example.okta.com/auth/saml20/jfranusic"
                                               />
            </saml2:SubjectConfirmation>
        </saml2:Subject>
        <saml2:Conditions NotBefore="2019-01-08T18:59:37.100Z"
                          NotOnOrAfter="2019-01-08T19:09:37.100Z"
                          xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                          >
            <saml2:AudienceRestriction>
                <saml2:Audience>https://www.okta.com/saml2/service-provider/spiixyrx8B2xDfEW20x6</saml2:Audience>
            </saml2:AudienceRestriction>
        </saml2:Conditions>
        <saml2:AuthnStatement AuthnInstant="2019-01-08T19:04:37.100Z"
                              SessionIndex="id1546974277098.1270582184"
                              xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                              >
            <saml2:AuthnContext>
                <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
            </saml2:AuthnContext>
        </saml2:AuthnStatement>
        <saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
            <saml2:Attribute Name="FirstName"
                             NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
                             >
                <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xs:string"
                                      >Joël</saml2:AttributeValue>
            </saml2:Attribute>
            <saml2:Attribute Name="LastName"
                             NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
                             >
                <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xs:string"
                                      >Franusic</saml2:AttributeValue>
            </saml2:Attribute>
            <saml2:Attribute Name="Email"
                             NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
                             >
                <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xs:string"
                                      >[email protected]</saml2:AttributeValue>
            </saml2:Attribute>
        </saml2:AttributeStatement>
    </saml2:Assertion>
</saml2p:Response>

@jpf
Copy link

jpf commented Jan 8, 2019

(For what it's worth, I use the "SAML tracer" plugin in Firefox to capture these sorts of payloads)

@suchitagarwal
Copy link
Author

hey @jpf havent checked in a while, but let me get back to you by tomorrow with the latest payload that i can find. thanks for jumping in

@andkrist
Copy link
Contributor

andkrist commented Jan 21, 2019

I checked the response from @jpf and a couple more and it doesn't seem like it's related to the IdP's.

@jpf's example from Okta:

<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity>
http://www.okta.com\exk410hnrc2i3lsMb0h7
</saml2:Issuer>

Parsed to:

"issuerOkta" : {
  "_": "http://www.okta.com/exk410hnrc2i3lsMb0h7",
  "$": {
    "xmlns:saml2": "urn:oasis:names:tc:SAML:2.0:assertion",
    "Format": "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
  }
}

From the sample-connection at OneLogin:

<saml:Issuer>
https://app.onelogin.com/saml2
</saml:Issuer>

Parsed to:

"issuerOneLogin": "https://app.onelogin.com/saml2"

From my OAM:

<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion
                     Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity
                     >http://www.someOrg.com/swag
</saml:Issuer>

Parsed to:

"issuerOAM" :{
  "_": "http://www.someOrg.com/swag",
  "$": {
    "xmlns:saml": "urn:oasis:names:tc:SAML:2.0:assertion",
    "Format": "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
  }
}

Xml2js uses _ and $ as default keys for charvalues and attributes. When there are no attributes, the charvalues are returned as string. Adding or removing attributes from any example causes this behavior.

Some places in ../saml.js the xml2js parser config is set to explicitly use _ regardless of attributes being present, by setting explicitCharkey: true. This ensures an element is returned as an object with $ and _ even if the namespace qualifiers are not missing.
Instead of using issuer._ || issuer[0], I suggest using explicitCharkey: true for the parser config, so you can always expect it to be accessed in '_'.

Maybe XML parsing of the Response should be moved to its own function to ensure uniformity?

@andkrist
Copy link
Contributor

andkrist commented Jan 21, 2019

This means that the PR from #187 wouldn't break conformity/spec or pander to major vendors. But the PR fixes a problem that should be solved in the parser config.
You can config the parser to call it 'value' or whatever instead of '_', so issuer.value would look better than [0] in my opinion.

@markstos
Copy link
Contributor

@andkrist, thanks for the analysis.

Instead of using issuer._ || issuer[0], I suggest using explicitCharkey: true for the parser config, so you can always expect it to be accessed in '_'.

Maybe XML parsing of the Response should be moved to its own function to ensure uniformity?

Both these proposals seem sounds to me. explicitCharkey: true is certainly more readable than referencing "issuer._".

<checks>

I was hoping that explicitCharkey would be documented in the xml2js documentation, but it's not really documented there, only the default value is mentioned:

https://www.npmjs.com/package/xml2js#options

It would also be helpful if a PR was submitted to xml2js to explain there was the explicitCharkey option does.

@andkrist
Copy link
Contributor

andkrist commented Jan 22, 2019

What bothers me about the docs is the default behavior when an element without namespace qualifiers is parsed.

Setting explicitCharkey: true while charkey : 'whatever' we can access all values through issuer.whatever/ nameID.whatever instead of _ || [0]

I think issuer.value looks decent.

I'd be happy to submit a PR to this repo to add some uniform xml parsing.

@markstos
Copy link
Contributor

Thanks, @andkrist

@markstos
Copy link
Contributor

markstos commented Feb 9, 2019

@andkrist: The next release is scheduled within a week if you want to get this PR in soon.

@andkrist
Copy link
Contributor

andkrist commented Mar 7, 2019

Submitted PR just now.

@cjbarth
Copy link
Collaborator

cjbarth commented Mar 7, 2019

That would be PR #361

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants