
How SAML 2.0 Authentication Works - gk1
https://gravitational.com/blog/how-saml-authentication-works/
======
api_or_ipa
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](https://github.com/bergie/passport-saml)

~~~
niftich
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.

~~~
timv
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_.

~~~
kellenmurphy
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.

------
CaliforniaKarl
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](https://aws-console-
idg.stanford.edu) redirects you to
[https://idp.stanford.edu/idp/profile/SAML2/Unsolicited/SSO?p...](https://idp.stanford.edu/idp/profile/SAML2/Unsolicited/SSO?providerId=urn:amazon:webservices),
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...](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html)

~~~
rukenshia
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...](https://aws.amazon.com/premiumsupport/knowledge-center/aws-
cli-call-store-saml-credentials/)

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

~~~
CaliforniaKarl
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.

------
robmccoll
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.

------
abhchand
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.

------
asadlionpk
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?

~~~
maxymajzr
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.

~~~
recursive
> 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.

~~~
CaliforniaKarl
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.

~~~
recursive
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/](https://www.shibboleth.net/products/service-provider/) It basically
seems pretty opaque. The downloads at
[https://shibboleth.net/downloads/service-
provider/latest/](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.

~~~
labanna
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/](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/](https://samltest.id/) to test against an IDP.

Shibboleth SP docs:
[https://wiki.shibboleth.net/confluence/display/SP3/Home](https://wiki.shibboleth.net/confluence/display/SP3/Home)

~~~
identigral
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.

~~~
recursive
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.

~~~
identigral
If your app is .NET, look at Sustainsys
([https://saml2.sustainsys.com/en/2.0/](https://saml2.sustainsys.com/en/2.0/))
or ITFoxtec
([https://www.itfoxtec.com/IdentitySaml2](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.

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

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

~~~
kabes
Yep, would also really like a single signout example

------
johnorourke
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.

------
identigral
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...](http://docs.oasis-
open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html) . 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)

