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

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.

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.

Identity Server 3 - Silent sign-in / sign in without login page. Including single sign on

I have come across a number of articles that discuss a similar matter but I cannot find a definitive answer.
My company would like to begin using Identity Server 3, however one of the requirements is to be able to authenticate an external user without them having to manually enter their credentials.
This must be capable of providing single sign on capabilities also as we have 3 different systems and our users should only have to sign in once.
Essentially, the external user has their own CRM.
The CRM holds their username and password for our software.
They then click a button in their CRM to launch our application
This redirects them to our website with a payload containing their credentials
We call a web service to authenticate the user
It is fundamental that we do not change this process for our partners.
Can I implement a custom service provider to provide the authentication or is there some other way of achieving this? If so, could you point me in the right direction for how this can be done?
Many thanks
Craig
I would assume that you'd create a mechanism for their CRM to get a token at the time the client logs into their site and then have them send that token via url to your callback page. This would use the machine-to-machine type grant, or the client-credentials flow. Then that page could validate the token and log the user in. There would have to be some sort of unique identifier between the two systems like email or something. Just an idea.

Providing "login_hint" on server side Azure Mobile App

I am using Azure MobileServiceClient to authenticate with a mobile app. I want to enable a secure logout function, which involves deleting the cookies created by the web component. Otherwise anyone selecting "Login" will simply get logged in if there's an unexpired cookie lurking around. Deleting the cookies is working great.
Unfortunately, it means that a user returning to the same provider on the same device has to provide their username again (clearly, I don't want to store their password).
I found out how to make it work with Google. (Google OpenId doc) I simply provide a dictionary of parameters to the LoginAsync method. That dictionary contains the key "login_hint" and the user's email address (which, btw, has to be valid to work).
This doesn't seem to work for Facebook, Microsoft or Twitter accounts and I don't know why. I read a document that said that "login_hint" or "username" was supported by convention, but none of that seems to work.
Anyone have any experience (even a completely different approach) with this they can share?
TIA.
In order to implement IdP provided solutions like that, you need to move to a client-flow authentication. Client-Flow is when you use the IdP provided SDK to authenticate the user. Once the IdP has given you a token, you pass that token (silently) to Azure Mobile Apps to exchange it for a ZUMO token that you can use with the Azure Mobile Apps service.
Once you have the client-flow enabled, you can do anything that the IdP (Facebook, Google, etc.) will allow you to do. It's not really an Azure Mobile problem - more of an IdP problem.

IdentityServer 3 securing webAPI with User Informatioin

We have a need to secure our .net web api using open id and OAuth standards. IdentityServer 3 is perfect for us as we have to use our existing user store.
Edited for more clarity:
Our company services multiple customers. Each of our customers have their own database. In our home grown client application when a customer user enters their user/password, we do a lookup to authenticate and that also determines what backend database the app connects to.
We now have a need to allow a couple of trusted partners to access our database resource for specific needs. We have created a web api for them to make specific calls. The web api needs to know what customer the partner is making the call for. The partner is calling the api from services on their side so there is no user interaction.
I am trying to determine the flow to use to accomplish this. I found some pretty good info on flows at https://gist.github.com/jawadatgithub/638c11f08ecc0d76b05c.
If I define the client using the Client Credentials flow, I don't know how for them to pass the customer they are making the calls on behalf of. I don't think we want to definate a "Client" for every partner/customer combination, but is this the correct way?
What we had thought of initially is to give an additional user/password or secret key that would tell us the customer, but I am not sure what "flow" for the client would allow this.
Any help or direction would be greatly appreciated.
In case this helps anyone else, we decided to go with a Hybrid flow for these types of requests. We considered designating a service account (user/pw) for each of our customer databases that would give this trusted 3rd part access to them by requesting tokens with the Resource Owner Password Credential flow, but decided against it. We decided against it for all the reasons the standards say not to use it for this use.
If the 3rd party wants to interact with us on the behalf of one of our customers, then they will need to build the UI on their side to redirect to us for user/pw authentication and consent.

How to authenticate without hitting the database?

A comment below an answer about state and REST recently piqued my interest. For clarity I'll quote the comment in full:
Nothing in my answer implies a solution based on database access on every request, if you think it does, it is a failing on your part to understand authentication and authorization at that scale. The authentication can be implicit in the state, do you think that facebook does a "database access" on every request of its REST API? Or Google for that matter? hint: no
I tried to think how one might authenticate without checking a user-provided value against a centrally-held one, even if one to know what data to display to the user, and came up blank. i freely admit this is a failing on my part to understand authentication and authorization at that scale. My question is therefore: how do sites like Facebook and Google accomplish this?
One way is claims based authentication. Simplified and somewhat loosely interpreted, it boils down to this;
Instead of the server application authenticating the user itself, an un-authenticated user is redirected to a separate authentication server.
The authentication server validates the user in any way it wants to (login+password, certificate, domain membership etc) and creates a signed "document" with the relevant user info (user id, name, roles, ...) It then redirects the user back to the server application with the document enclosed.
The server application validates the signature of the document, and if it trusts the signature, it can use the document contents to assume who the user is instead of accessing the database.
Normally, the server application caches the document in a cookie/session or similar so that the next access to the application does not have to bounce through the authentication server.
In this way, the server application does not need to concern itself with how the user is authenticated, just whether it trusts the judgement of the authentication server. If the authentication server (and possibly the client unless it's a browser) adds Facebook login support, the server application will automatically "just work" with the new login type.