1) Insist on encryption of the SAMLResponse (that way, the SP has to do it correctly, or they'll have no idea who is accessing the app) 2) If they won't do encryption, I test exactly what they are talking about in this article
To test, I have my own IdP set up, and I either do IdP-initiated sign-on or spoof the IdP URL using /etc/hosts on my localhost and try to log into the app with a signed SAMLResponse using a key the SP doesn't know about. If it works, I immediately tell our CISO. I even scared one vendor so badly just explaining that I was going to do this that we never heard from them again.
If you use a separate encryption key for each SP, then great - but you could just as easily use a separate signing key, as the article suggests, and far more SPs support this.
Of course, it is still possible the SP does not validate the signature at all, or does so erroneously.
You're right that per-SP pairs are still the right answer and for the reason you point out: much wider support.
You can't drop that and walk away without naming them.
What the article is saying is a bit nuanced in that the IDP can theoretically provide a different user identity for each service, but in reality, does that really happen? Seems like if you're doing that you're starting to mix authentication with authorization.
The picture in the article that says that the idp provides the answer to "login to cat", "log in to to payroll" is wrong imho. the IDP is providing the answer "username is X", and that's it.
It's not a scenario you're likely to see in the case of corporate SAML use, where people generally don't care about anonymity to SPs, but it happens fairly routinely in Shibboleth environments with multilateral federation. In that scenario, you often want proof of the user's membership of the organization (or their role within it) and the ability to track a specific user of the service, without being able to expose who the user is. In that case, your user identifier attribute ends up being an opaque ID, which is either random or a hash of username+SP-entity-ID+salt. Using that approach, there's no way to tell if user X at journal site A is the same as user Y at journal site B without the assistance of the IdP owner.
The problem is the SAML assertion is effectively a bearer token, which is fine if it's specific to a service, and not fine if it can be replayed. If you want to unmix "authentication and authorization" as you put it, you're going to need a way to bind that credential further. You can either do that with some unspecified scheme that nobody implements, or you can do that by just using per-SP keys as the article suggests.
What do you propose we do instead?
Or you have your IDP (say ADFS) only permit issuance for authorization requests which are appropriate, again by reference to (say) AD group memberships.
If your SP doesn't even validate the audience for the assertions, then you're definitely going to be in a bad place - but the question there is "how do I limit the damage this braindead SAML implementation can do to my enterprise and how do I make sure I never buy software broken like this again?" rather than a screed suggesting authentication and authorization are the same thing.
> Correction: SimpleSAMLphp easily allows for per-SP signing certs/keys. See https://simplesamlphp.org/docs/stable/simplesamlphp-referenc... (signature.certificate and signature.privatekey)
> SimpleSAMLphp’s IDP supports key rollover but no way to specify unique keys for individual service providers. There might be a way to configure it but if so, it’s not mentioned in the documention and I’m not excited to try it myself.
A Google search for 'php saml' has php-saml as the top result. I'm curious to know why you chose simplesamlphp over php-saml ?
This is probably something fundamental I'm misunderstanding about SAML, but when you authenticate for a particular SP, why does the response automatically include every assertion? It seems too obvious to just configure which claims are issued for each service provider. That wouldn't require any special crypto stuff.
I'm guessing I should: 1) Go into my Okta dev account, create a 2nd "okta app" (SP instance) pointing at my hosted application, which should create a new entity ID 2) Start an IDP-initiated login attempt from this 2nd okta app, and verify I get an audience mismatch error