thameera / saml-mock

SAML Mock IdP and SP
saml-mock.vercel.app
MIT License
13 stars 4 forks source link

The IDP page's "ACS URL" field could reference the AssertionConsumerServiceURL request attribute? #5

Closed janicki closed 1 month ago

janicki commented 1 month ago

Hi. First, thanks for this tool... It's been very useful for implementing a SAML integration for Microsoft's IDP, "Entra ID."

When my SP sends a SAML request to an IDP (e.g. Entra), it is supposed to include the SAMLRequest GET parameter. That param's value is a SAML request XML, (after being zipped, base-64 encoded, and URL-encoded). The XML contains an "AssertionConsumerServiceURL" attribute, and an "Issuer" content tag.

It would be a more-complete test (for Entra at least) if your IDP could automatically use those values contained in the request's XML instead of the explicit "acs_url" and "audience" params currently required in your sign-in URL. I can manually edit your form at "https://samlmock.dev/idp" (which is a great feature!), but automating those fields (by parsing the request) would be nice.

My SAML understanding is still a little shaky, so sorry in advance if I'm mistaken somewhere.

Also, my implementation uses Java's built-in javax.xml.crypto.dsig.XMLSignature to validate the IDP's signature. That does not accept SHA1. So I have to change your form to use SHA256. (Thanks for making that possible!) If it makes sense (i.e. if SHA1 is universally shunned now?), it would be nice if the form defaulted to SHA256.

Thanks! Chris

thameera commented 1 month ago

Hi, glad to know you've found the tool useful.

The reason it was designed to look at the query params only for acs_url/audience was that some IdPs like Auth0 do not send the AssertionConsumerServiceURL by default in SAML requests, and there would also be extra requirements (in the SP) for that to be present such as the request being signed. It does make sense to try to extract them from the SAML request if query params were not passed though - I'll implement that some time soon.

The reason for SHA1 being the default is again differences between IdPs as many still use SHA1. Good to know that Entra ID uses SHA256 by default - I'll look around to see if others have the same default behavior and consider updating this.

Appreciate the feedback!

janicki commented 1 month ago

Thanks for the info! Makes sense. I think I posted before I understood enough, sorry. Feel free to close. Below is FYI:

I think I made a bad assumption about AssertionConsumerServiceURL... That attribute is used by an old LastPass project I had studied. Entra doesn't seem to use that attribute, at least per this: https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-on-saml-protocol (I don't have access to Entra yet, which is why your tool is extra useful.)

Sorry, I didn't mean to imply that Entra requires SHA256. In fact Entra supports both SHA1 and SHA256, but does recommend the latter: https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-fed-sha256-guidance

My observation was that SHA256 seems to be required by the XML signature verifier build into core Java. (I'm not using the OpenSAML libs, which provide their own crypto.) So when trying SHA1 with your IDP, my SP's Java throws the following exception: "javax.xml.crypto.MarshalException: It is forbidden to use algorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1 when secure validation is enabled"

But it's happy when I select SHA256. Most people will probably use OpenSAML libs, which I assume don't complain about SHA1 (yet?), so my observation probably doesn't matter for most of your users.

thameera commented 1 month ago

Right, that confirms that many providers do not include the AssertionConsumerServiceURL in the requests. As for SHA1/SHA256 i'll wait to see if any other reports come up about the default value and potentially update this later.

Thanks for sharing your findings. I'll close this for now.