SAML account binding/linking (with Okta) - saml

I'm in a process of implementing SAML 2.0 based SSO capability for a web application. So far, I've managed to successfully use/test Okta and Ping (which are at the moment the main target IdPs however, the goal is of course to be compatible with any SAML 2.0 compliant IdP) to authenticate users. The next step would be to enable account linking/binding between my application and the IdP. Since accounts on my web app are based on email addresses, I'm leaning towards a solution where email would be used for account linking/binding.
First of all, I'm interested in whether this is considered good practice (using email to link accounts), e.g. is there a possibility that there could be an IdP where it's not possible to get user's email or where it would be considered insecure (in case users can change their email addresses).
Next, I would appreciate any pointers on what would be the most preferred and most widely supported mechanism for achieving account linking. Based on what I've read so far I see these options:
Instruct my users to configure their IdP to send user's email as an attribute. For example, when configuring Okta, there's a "Attribute Statements (optional)" section where one can define an attribute with name "email" and value "user:email".
Include saml2p:NameIDPolicy in my SAML requests and set its Format to "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
Instruct my users to configure their IdP to send email in the assertion's subject statement. For example, when configuring Okta, there's an options to specify "Name ID format" where EmailAddress is one of the choices, and there's "Application username" where Email is again one of the choices.
Based on initial tests so far, these are my conclusions. Option 1 works both with Okta and Ping, however this feels a bit custom, i.e. less standard. Could there be IdPs that don't support sending attributes or providing emails in the attribute section. Option 2 feels standard, but Okta seems to ignore the NameIDPolicy element, so it basically won't work with Okta. Ping on the other hand honors NameIDPolicy but only supports emailAddress and unspecified formats. Could there be IdPs that don't support emailAddress format? Option 3 seems like the least reliable solution. In Okta, subject's value is the same no matter what I specify as the "Name ID format" and "Application username", while Ping doesn't event provide a way to configure this. On the other hand, by default (next, next, finish style of configuring an IdP) both Okta and Ping are sending email addresses in the assertion's subject.
Finally, in case that use of an email address is discouraged for this purpose, I guess any kind of a persistent identifier could be used instead of an email. However, users would then have to go through some kind of binding/linking process (for example by generating linking tokens, and sending links containing these tokens to user's via email).
Which of the 3 options I mentioned would be most likely to work in the real world, i.e. which is the best supported/enabled by different IdP providers. Am I perhaps completely off base and this should be handled differently? Any pointers and best practices on this subject would be appreciated.

Related

When we tell our customers that our website "supports" SAML 2.0, what would they expect?

So, when management tells us our website needs to "support SSO through SAML 2.0", with no additional details, what are they thinking?
What will our customers expect?
Note - The is not an open website, where everyone can join. To log in you need to be a configured user in the system. The customer's admins need to create an account in our system for each user.
So we aren't going to let just anyone who has an account with an IdP in to our website. We'll have to have some mechanism for mapping a SAML identity to our users.
How would our customers expect that to work?
Based on hints in your question, I am going to presume that you will be acting as a service provider.
To be what I would call a "good" service provider, I would expect the following:
You sign your AuthnRequests.
You provide a metadata endpoint that is kept up to date with your SP metadata to include current public keys for encrypting attributes (if necessary) to be sent to you as well as validating your AuthnRequest signatures.
You support dynamic consumption of my identity provider's metadata endpoint to keep your side of the connection up to date, especially with concern to my signing certificate.
You expose management of my identity provider configuration inside of your service provider mechanism to my IdP administrators through a web or API interface.
You either support a mechanism to automatically manage my users (like via SCIM or Graph or something else), or you support Just-In-Time provisioning based on an incoming assertion.
You allow me to decide my SAML Name ID format, and that format is per-tenant. As an example, I may want to use email address as the identifier, while another IdP may want to use sAMAccountName. e.g., john.doe#domain.com vs. johndoe.
You support Service-Provider-Initiated SSO. That means that the user shows up to partner1.yourdomain.com and get redirected for authentication to that partner's IdP, and that going to the location partner2.yourdomain.com would redirect to a different IdP.
As a service provider, you should make using your service easy and secure. By shifting to SAML, it allows you to get out of the business of password and user management because you get to put that back on the identity provider. It allows your users to not have to type in a password (or more, if you're doing MFA) to use your service, removing friction caused by security. It allows you to put the onus of authenticating the user back on the organization that owns the identity.
Your customers would expect that if they have an application that uses the SAML 2.0 client-side stack then when the application sends an AuthnRequest, they will see a login page on your site and once authenticated, the application will receive a set of assertions (claims) from your IDP via an AuthnResponse.
One of these assertions is NameID. This is the "primary key" between their system and yours. Normally this is UPN or email.
This mapping is outside of the SAML spec. There needs to be some kind of "on-boarding" for the customers.

How should mapping of service provider users to identity provider users work?

I'm working on setting up a service provider that supports SAML. I've added two identity providers - one custom one that I built from SimpleSAMLphp and then ssocircle. So I log in to the selected identity provider, and then it returns to my service provider and I inspect the attributes of the SAML Auth object. The identity provider I built returns whatever I want it to (obviously). The ssocircle one only returns e-mail, first, and last names.
So now to map this to the user of the service provider, I have to use some value the identity provider provides. So this led me to wonder how it should be done. Since ssocircle only gives me e-mail as a useful value, do I just use the e-mail to map to the SP user?
Let's pretend for a second that ssocircle doesn't validate e-mail addresses. So now if I create a second account at ssocircle with the same e-mail, I can log in as my coworker who I know has admin privileges.
So my question is, do I handle this? Or is the onus on the admin who set up the identity provider and say "well you shouldn't have used an identity provider that doesn't validate e-mail addresses!" or something of that nature? Or should I only allow identity providers that pass a certain value, like userid or 0.9.2342.19200300.100.1.1? Is there something that identity providers commonly use?
Well, you said it, two different identity providers. They both should be passing not only the email but different entity ids and certificates.
In multi-tenant applications that would mean two different applications, but if you plan to allow multiple IDPs to point to a single app you will need to ensure that same email but different entityID create two different users and or throw an error after the first was created that the second cannot be provision nor access.
Interesting question. These days people think always of auto federation of users by some attribute. In early SAML federation days federating two unrelated users was a manual step in which a user logs in at the IDP and logs in to the SP providing both sets of credentials and then manually federated these two user accounts. The process guarantees that only the user who has access to the accounts at the IDP and SP controls the linkage between the two. It also allows anonymous naming identifiers (SAML persistent NameIDFormat) which protects privacy because even the IDP does not know the user name at the SP and vice versa.
Unfortunately the process was to complicated for users and with the success of OpenID the aspect was getting less and less important.
To answer your question: What you describe happens in the real world -see Office 365 authentication bypass
You need to check that the IDP is authoritative to send a specific attribute and attribute scope in case of two IDPs.
In case of one IDP the attribute must be verified (SSOCircle verifies email address) and it should better be unique (For example SSOCircle userId) to avoid that two users with the same attribute are mapped to a single user at the SP.
If the userid's are not the same (e.g. you use a simple user ID at the IDP and email address format at the SP) you can still add a correlation attribute at the SP (e.g. an attribute named ssocircle-userid) and use that to link the user accounts.

InvalidNameIDPolicy working with ADFS

I have many clients that uses SSO, for that we use SAML 2. Many of my clients uses providers like Okta, PingIdentity and a bunch of them ADFS. Doing the integration with ADFS always at the beginning raises this error when they came back with the SAMLResponse.
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Requester"><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"/></samlp:StatusCode></samlp:Status>
Im asking to use as name Identifier this:
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
Im pretty new to SAML and I just want to know what is happening on ADFS, since this is just happening with clients that uses that.
Thanks a lot.
By default, ADFS sends the NameId format as "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified". You can adjust it. See: https://social.technet.microsoft.com/wiki/contents/articles/4038.ad-fs-2-0-how-to-request-a-specific-name-id-format-from-a-claims-provider-cp-during-saml-2-0-single-sign-on-sso.aspx
The other way to do this is to identity what attribute needs to be mapped to NameID e.g. email address.
Have a normal LDAP rule for email.
Then have a Transform rule that transforms email to NameID and select the NameID format you need from the drop-down.

Additional EntityID or Binding on a Single ADFS Server?

I'm a programmer with VERY limited system experience, and I've set up an ADFS 2.0 Rollup 3 server for authentication to Salesforce.
My use cases are:
1. Allow single users to authenticate against their NameID in the UPN.
2. Allow group users to authenticate by membership in a user group.
I would like to have both types of authentication on the same ADFS server. Here is an example of the sign-on screen, where the "Active Directory" button is for single users, and the "Admin Users" are members of a user group.
I have no problem with either group authentication or user authentication on a single ADFS server, but I'd like both on the same ADFS server for a single relying party trust. However, I haven't been able to get that to work.
The entityID is the default,
http://[Server Name]/adfs/services/trust
The login URL is the SAML 2.0 endpoint:
https://[Server Name]/adfs/ls/
I've tried several things that didn't work:
SalesForce requires the "issuer" (in this case, the entityID) and the "login URL" together are unique, so I've tried adding URL parameters to the login URL, since those will get imported into ADFS from the metadata file. That doesn't work though - If I have two relying party trusts, one w/ the parameters, and one without, I'll get signed into one, regardless of which one I'm trying to sign into.
I've also tried adding multiple rules to one, but that generates an error when I try for SSO.
How could I get this to work?
If anyone ever stumbles across this, in order for this to work, the simplest solution is to send different relying party IDs from SalesForce, and have different relying party trusts in ADFS.
In SalesForce, this would appear as two different buttons on the login screen, and in ADFS, this would appear as two different relying parties - One in each system for each relying party ID.
If you are auto-signing in from some application, you'll have to iterate over each relying party trust, and try to authenticate from each.
I can't imagine this very specific use case will be much value, so comment if you want more details, since my 3 year old question has little interest :)

How to get ADFS to respond to a query about an user's email address

I'm working in a company that uses Microsoft Active Directory. We have an external company that provides an internal web site for a particular project. The site is external to the company. The sign on to the external site is the user's company email.
We want a system whereby the external site calls into the organisation's AD to verify if an email address is still valid or if the user has left the company. It should be a simple call to Active Directory Federation Services or some sort of SAML interface. The call would be a simple request 'here's an email, is it valid?' and the response is either yes or no.
Our IT department are trying to tell us that it's too complicated and I don't believe them. I think they just don't want to do it.
Does anyone know how easy it would be to create a simple system that would allow an external service to do the query outlined above.
ADFS is not meant to do that. However, a by-product of using it, would be the validation you are looking for.
The first question would be: what is the authentication method of your app? e-mail and what else? password? which password? Does the app keep a database of users/passwords?
ADFS works as an "identity provider" and would authenticate users in AD. ADFS would supply a security token that can be consumed by your app. Part of the information sent in the security token could very well be (and often is) the user e-mail address (that's why it is a "by-product").
For this to work, the app would have to be changed to accept security tokens (SAML tokens to be specific). If the app is .NET based, then it is done usually with WIF (WIndows Identity Foundation).
This approach would be the most elegant and secure because the app would delegate the responsibility of authenticating users to the authority of these employees: AD.
App --trusts--> ADFS --authenticates--> AD
Setting up ADFS, etc is not super-difficult, but it is not super-simple either, and might not be worth just for this app. There are other lighter weight alternatives: open source products like Identity Server, or products like the one I work on.
Now, if all you need to do is to validate that the e-mail actually exists, the best is to send a verification message to that address with some unique code that the user sends back. This is the same approach used in many common web apps.
Agree with everything #Eugenio said - have same questions about authentication.
But if you simply want code to query an user's email address in AD, you use the AD API's.