Hacker News new | past | comments | ask | show | jobs | submit login
How SAML 2.0 Authentication Works (gravitational.com)
214 points by gk1 on July 29, 2019 | hide | past | favorite | 36 comments



Great article. I had to integrate SAML 2.0 in a product not-too-recently and it's absolutely horrible compared to Oauth workflows. Maybe it's the different ecosystem: most IDPs are big, bureaucratic institutions with tons of middlemanagement where OAuth providers tend to be tech orientated players looking to scale their product with minimal friction. Anyways, tons of documentation is outdated, or too light on details or orientated towards management rather than developers.

passport-saml [0] really deserves more love for how (mostly) wonderful it is at making integrating SAML into node applications.

0: https://github.com/bergie/passport-saml


As a SAML IdP operator, you're not wrong -- the typical SAML IdP operator is an insitution or a BigCo's internal SSO, while the typical OIDC/OAuth provider is a tech company that runs a data silo -- but consider that SAML IdPs and SPs frequently have to engage in a dialogue to peform an integration, while OAuth 2.0 providers just kind of exist by fiat, and wait for SPs to show up. OIDC evolved from OAuth 2.0 so the UX expectations remain: the SP's operator expects to have to go through some web-based SP registration process provided by the OIDC IdP.

In SAML, the IdP and SP can exchange metadata, but plenty of fly-by-night SPs can't consume it, and need to be configured by hand. Tons of vendors of claim their SP supports SAML, but their implementation was hacked together in someone's basement and doesn't support SAML medadata, is hardcoded to use NameIDs, can't do key rotation, and the like. Some vendors intentionally "simplify" the terminology and translate well-specified SAML terms like "Assertion Consumer Service" to nicer sounding common words, like "login URL", largely obscuring meaning and making any integration an exercise of repeated trial and error.

Garbage IdP software exists too. The SAML specs are very accommodating and offer lots of options, so even among parties that don't flout the text of the standard, the interoperability matrix can be challenging. It's best if your product supports all the options, because the other guy's handmade product probably won't. Then, with attribute release and usage, some vendors ask for email address and use it as a persistent non-reassinable identifier, and some vendors ask for a persistent non-reassingable identifier and if it looks like an email, they'll probably send mail to it. It's frustrating.

Really, because each standard's deployment base, the incentives are different: the typical SAML SP offers a product it wants to sell to an institution or BigCo and the IdP is trying to be careful with its attribute release, while the typical OAuth provider is the data silo itself, full of user data, and SPs want to integrate with it to surface that data in their own application. OIDC then shipped a bunch of standard claims to carry identity info too, but the nature of the typical deployer has hardly changed.


I'm the technical point of contact at a SP. Integrating with enterprise IdPs is awful. Out of over a dozen integrations I've done only a single IdP supports metadata exchange. Most of them don't know what it is. Okta and Onelogin, and other IdPs might support metadata exchange, but they keep it fairly quiet.

Metadata exchange seems sketchy at best. I don't trust any enterprise IT organization to keep their metadata endpoint working.

I've finally got a 'self service' system dialed in where enterprise users can setup their SSO without talking to us at all, and typically they only need to enter a single value into the configuration form - the ACS url. Key rotation is supported, etc, etc.

It is a bloated yucky protocol, but when you just use "SAML The Good Parts" it isn't bad.


As someone who has built and maintains the SAML implementation for an SP it's funny how many of your complaints about bad SPs match my issues with bad IdPs.

Most IdP-as-a-service vendors produce their own metadata, but can't consume SP metadata. They invent their own terminology, make it hard to pass attributes, and rarely offer options around which binding to use.

It's unfortunately all too common to get into a situation where The spec says X and Y are valid. The interoperability profile requires X. But this popular vendor only implements Y, and does it incorrectly.


I'm a SAML consultant. I help IdPs become "good" IdPs, and I help SPs become "good" SPs. Both sides are usually bad in some way or another, and both sides usually want to shift the blame to the other side as soon as they can.

The number of times I've been CC'd on a terse email from one admin to another saying it's the other guys fault after I've clearly told them the list of things on their side that could be causing the issue is pretty much uncountable at this point.


This is a very helpful writeup,

I'm a SAML implementer and technical point of contact for a SP. I also have the unenviable duty of writing the "how to provision" documentation and doing our tech-rep training.

There are two kinds of IdP, in my experience: Microsoft's Active Directory / Federation Services (AD/FS) and everybody else.

"Everybody else" includes Ping Identity, which seems to be favored by very large companies. We also have a few users of the Computer Associates product and Okta. Other products we haven't seen yet in the wild include the Salesforce.com IdP and Onelogin. (Salesforce is interesting; they allow their instances to be provisioned as IdPs, SPs, or both.)

Almost everybody has been able to furnish Federation Metadata Endpoints to us; nobody has yet asked us for our Federation Metadata Endpoint data, which is good: we don't generate that.

AD/FS is a hassle. Typically of Ballmer-era Microsoft products, they changed the conceptual names of most of the protocol elements in their provisioning screens: they p*ssed on SAML until it smelt like them. So, I rewrote the docs for that IdP in Redmond Creole. Effective.

We have quite a few different AD/FS users; some from their Azure multitenant setup and others from on-premises AD / FS servers. Some multitenant AD/FS implementations provide multiple signing certificates in their federation metadata endpoints. Various Assertion xml-docs from them pick one of the multiple certs.

AD/FS has a convenient feature: its federation metadata is located at a standardized URL: https://federation.example.com/FederationMetadata/2007-06/Fe...

We implemented autoprovisioning, in which we create a profile on our service for any authenticated principal in a SAML Assertion we've never seen before. Some customers really like this as it gets rid of the need for upfront provisioning. But, I sure wish there were a standard deprovisioning protocol.

Chromium and Firefox both have nice SAML Web Extensions that render AuthnRequests and Assertions.

SAML is complicated and insanely hard to troubleshoot. But it's effective and seems (so far) to be secure.


Well most of the software is crap because almost all of them use Shibboleth, where every configuration is stored in ugly XML files and then a reconfiguration means restarting the service with new XML files.

SAML is very used at Government level and because Government likes JavaEE so much, but the libraries/frameworks implementing/offering SAML are pretty garbage


For Shibboleth, the XML configs are unwieldy, but both the IdP and SP are solid and eminently configurable, which is helpful when interfacing with someone else's broken software or odd requirements. In running our Shib IdP, I've had far more trouble with hand-rolled SPs (presumably using found libraries) than I've had with poorly managed Shib SPs. SimpleSAMLphp is comparable, if you're not a Java shop.

Commercial IdP-aaS products have their place, but with their spread, some SPs just code and document how to integrate with the two or three most popular IdP-aas products, and if you're using something else, you're left trying every possible binding, signing, and encryption, until you figure out which one works. Competent SP authors and operators can likely say similar things about various IdPs.

Despite the standards, it's nice if knowledgeable, accommodating people are running capable software on both ends of the exchange, and frustrations will probably increase the further you depart from that ideal.


This is my pet peeve with most single sign on providers. Either commercial products/services or bloated "over-engineered" solutions that are hard to customize.


Well. I didn't realize until now that oauth and saml are distinct things.


May I blow your mind? Have a look at https://cilogon.org — that is a service which takes a SAML Assertion, and returns to you either a client certificate or an OAuth authentication.

The link I posted above shows the client-certificate flow. If you want to see the OAuth flow, go here: https://demo.cilogon.org

CILogon is used alot in the Research & Education space. But if you don't have an institutional logon, that's OK, just select 'Google' from the list of providers.


Fun fact: In the AWS Console, you can set up SAML for users to log in. Instead of logging in as a specific IAM User, they are "logged in" to a specific IAM Role. You could almost say that their SAML login is "bound" to that IAM Role.

It is also possible for the IdP to tell AWS that this user is eligible to "bind" to multiple IAM Roles; the user selects which role to bind to after authenticating with the IdP. CloudTrail logs will include the IAM Role, and the identifier of the individual bound to that role. So if you already have a SAML IdP, you might not need a separate authority (like a Vault installation) to give temporary credentials to people.

The only annoying thing, is that the SAML login to the AWS Console is _not_ SP-initiated, it is IdP-initiated. It is more formally known as an Unsolicited SSO (in that the SP is suddenly getting a SAML assertion it did not ask for). So you have to know the correct way to initiate this on your IdP. In our case, browsing to https://aws-console-idg.stanford.edu redirects you to https://idp.stanford.edu/idp/profile/SAML2/Unsolicited/SSO?p..., which starts the Unsolicited SSO.

You also need to configure your IdP to include some AWS-specific SAML attributes in the response, telling AWS what role(s) the user is allowed to use. This can be annoying, but in our case the group managing the IdP simply scripted it, so adding a new IAM Role is not a big hassle.

Information on how to configure this—for both the AWS side and the IdP side—is available at https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_pr...


We've been using SAML to log in to AWS for the better part of a year now and it's been pretty good for us.

When logging in, you assume a role (sts:AssumeRoleWithSAML), I'm surprised you did not mention the worst part: logging in to the CLI with this. You either have to manually input the returned SAML assertion to the AWS cli[1], but luckily there is a tool called saml2aws[2] to do this with the majority of identity providers.

saml2aws sadly didn't have proper support for assuming many roles at once, so we even ended up writing our own tool for this.

This is something AWS has completely ignored so far and I am not aware of any progress towards a better CLI experience.

[1]: https://aws.amazon.com/premiumsupport/knowledge-center/aws-c...

[2]: https://github.com/Versent/saml2aws


Ah yes, you’re right. I had completely forgotten about this, simply because I haven’t used it. But yeah, it’s a big annoyance for a lot of people.


SAML is a simple enough in concept (I as SP don't know who you are, but I am configured to trust IdP, so if you can get a signed document from IdP saying "the bearer of this document is X", then I'll trust that), but XML canonicalization and signing is a pain to get right, validation has a number of gotchas, the standard has too many optional parts and is too configurable, and it's difficult to test conformance. Having implemented both SPs and IdPs before, gotten them wrong in a few subtle but dangerous ways before getting them right, and having had to test against a variety of IdPs and SPs before determining that it was mostly compatible after adding a bunch of IdP-specific configuration parameters, I don't recommend SAML 2.0 itself if it can be avoided.

OIDC isn't perfect, but it is much better. The entire assertion is a JSON Web Signature, so there's no opportunity for ambiguous extra unsigned data and the canonicalization is dead simple (UTF8 base64 URL of bytes). Fewer optional components. Smaller message sizes.

Edit: if you need a SAML IdP for your organization, I had great experiences with Okta. Ping was opaque, less flexible, and overly complex. Didn't do the configuration side of ADFS, but it wasn't particularly hard to communicate with.


Clear and simple guide. I struggled to implement SAML login for so long on a project because every guide is just a long enterprise wordy document or doesn't correctly defines terms and concepts.


How does the logout process work?

Or what happens when the user is removed from the idp? How does service provider know the user is supposed to be logged out?


In most cases, SP doesn't know user is removed from IdP. If there's a need for such feature, you resort to shared sessions - IdP has control of storage service where SP's save sessions (say, Redis). Once user is removed from IdP, IdP deletes the session record in Redis and SP loses all user info.

This implementation happens rarely.

The single logout process is often flawed since it depends on SP's accurately processing the request and returning the user back to IdP if a session has been successfully destroyed. This often fails due to network connectivity, problems with session destroying at the SP, SP's not implementing the SingleLogout properly etc. What I've experienced and seen in many cases is that IdP simply kills the session it has on the user and stops right there, then the rest of the SP's handle it through back-channel.

I work in this area so I'm relaying my experience through past 10 years of implementing SSO for various enterprises.

In reality, the SAML protocol is quite straight-forward but something odd happens when people hear the term SSO. It's not magic, it's quite trivial but takes a bit of discipline to grasp it fully and implement properly.


> it's quite trivial

I've been tasked with authenticating in an existing application via SAML 2.0 I've got the whole SAML 2.0 specification printed and sitting on my desk right now. It sure doesn't look trivial.


When people say "Don't roll your own encryption" or "Don't implement $ALGORITHM, just use libsodium", I think that also applies to web authentication (be it OAuth or SAML).

If you are the 'client' that wants to authenticate an incoming user, then I'd point you to an existing SP like Shibboleth or SimpleSAMLPHP or even CILogon (which bridges SAML and OAuth). If you are handing out authentications, then you are an IdP and I'd point you to something like Shibboleth or ADFS or Okta.

It is good to have the relevant RFCs to hand, but I would not make an implementation from scratch, unless there was a very good reason for it.


I'm trying to build an "SP" or "relying party" as I've learned in the jargon of the domain. Building an implementation from scratch is the last thing I want to do. I feel like I'd rather pull out my own teeth. But a difficulty of finding any information about it has lead me to start reading all the official specs as a kind of last resort.

In my initial research, I did discover Shibboleth, but was under the impression that it was an IDP only. I will check out the SP component, because I would love to not implement it from scratch.

At first glance, I see this: https://www.shibboleth.net/products/service-provider/ It basically seems pretty opaque. The downloads at https://shibboleth.net/downloads/service-provider/latest/ don't really provide much clue of how to build them or incorporate them into my app, which is written in a different language than any of these source files. I'll keep looking.


I was just tasked last week with implementing SAML auth for our applications and have settled on Shibboleth.

For the SP I just installed it from yum after adding the centos repos.

There is a repo config generator at https://shibboleth.net/downloads/service-provider/RPMS/ that I used.

It installs as an apache module and I am building a flow from my load balancers to hit the apache/SP and proxy some traffic to the application after authentication success so we can create our login session.

I have a PoC going now, but the documentation is not terribly clear to me and it is really confusing me about some options I need to tune.

For my initial testing, I built the SP and used https://samltest.id/ to test against an IDP.

Shibboleth SP docs: https://wiki.shibboleth.net/confluence/display/SP3/Home


If your language/environment supports using Apache HTTPD as a proxy, then you can use mod_auth_mellon to secure your web application. That's just one option, there are lots of others.


I have heard about these options, but the problem for me is identifying any of them and figuring out how to use them. My web server probably has to be IIS or Kestrel. I've been trying to figure this out for a few weeks now. And I've spent about a day trying to figure out how to do anything with the Shibboleth SP. I think I got it installed, but I can't really tell if it's doing anything or how to use it. And even then, there doesn't seem to be any information on how to actually use it for authentication in my application.

From my perspective as an application developer, writing an application that authenticates via SAML 2.0 is a nightmare, despite the ubiquitous claims of how simple it is.


If your app is .NET, look at Sustainsys (https://saml2.sustainsys.com/en/2.0/) or ITFoxtec (https://www.itfoxtec.com/IdentitySaml2) libs. Unfortunately there isn't a clear architect/dev-level guidance at the protocol level on key decisions that need to be made when implementing SP that tightly integrates with your app. Give one of these a shot and post your questions on StackOverflow.


Thanks. This looks more approachable. I'll give these a shot.


If you're willing to use PHP, there's also "the award-winning" SimpleSAMLphp (https://simplesamlphp.org/), which can operate as IdP or SP. I can tell you that many big names in the TV Everywhere space are using it.


You're reading the entire spec, but the flow is what's trivial. 2 systems are exchanging info, they use cryptograhpy to assert that message is coming from a valid, registered resource and the message carrier format is XML. You ask for info, you get XML back, verify the sender and if correct trust the info is valid. That's the gist of the protocol and the tedious part is parsing the XML you receive.


The flow/concept is simple indeed. But with saml the devil is really in the details and they created way too many details by offering way to many options in the spec.


What's the best practice on when a user session is destroyed at the SP's end? After receiving the LogoutResponse from IdP or before sending the LogoutRequest to IdP?


The other responses answer your direct question, but I was confused about similar flows when learning about SAML so I'll comment in case this is helpful.

SAML is just an authentication protocol, it doesn't really handle user provisioning. Which was confusing to me, because any time you'd use it you typically also need some kind of provisioning mechanism.

SAML does have a concept of "just in time" provisioning, which is what I've seen small SAAS companies typically support when they say they have SAML support. But basically all it can handle is creating accounts in the SP the first time a new person logs in (with valid credentials signed by the IDP). For user provisioning though what you really need is full programmatic CRUD access for accounts in the SP, which is outside the scope of SAML. I don't really understand why the SAML protocol bothers having such half-baked support at all, because you immediately run into issues. For example, giving some users different permissions than others in the SP, or updating accounts in the SP that already exist.

For user provisioning, for SPs that support it you can use the SCIM protocol alongside SAML, which gives you full control over provisioning accounts the way you need to. Then for instance instead of just logging someone out of the SP when they were removed from the IDP, it can fully deprovision the account in all your SPs as well so you're not left with orphaned accounts sitting around.


http://xacmlinfo.org/2013/06/28/how-saml2-single-logout-work...

The scenario you describe would be addressed by a logout request or session expiration.


As usual in this kind of articles, the logout process is left out...


Yep, would also really like a single signout example


Shout out for simplesamlphp, which confusingly comes as two projects: simplesamlephp/simplesamlphp (a full web application which can implement SP or IdP), and simplesamlephp/saml2, a library of components for parsing and building SAML messages. I just used the library, which meant building a lot of the logic around what to actually do with the messages, but once you've learned the protocol inside out, it's easy to use ( as ever, the code IS the documentation!) but has a few limitations - because it was built to support a specific application. One very handy feature (relating to others' commenting about SPs that can't parse metadata) is the metadata parsing.


For a technical intro to SAML, the best place to start is the original OASIS Technical Summary doc at http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-t... . It's still very much relevant and it doesn't gloss over important details (profiles as a central concept, profiles other than web browser SSO [such as single logout], multiple bindings in a profile, etc)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: