As companies begin to grow larger and more complex, most successful companies find themselves with a multitude of applications to manage, each with their own set of users and authentication. With the advent of Office365, Azure Active Directory, and the the ubiquitous Google Application Suite, more and more user accounts need to be managed. Single Sign on “seems” like the ideal solution, but it has it’s own problems. We’ve found, however, that it is really the best solution currently available.
In our situation, we generally have systems that we’ve already built, or systems that another developer has built and we have taken over. Each have their own user tables, their own authentication methods, their own way of managing permissions within that app. Single Signon “can” bring much of that mess together. I’m going to explain a bit about how it actually works, how we implemented it and then show some samples.
The first thing you need to know is that this is an “Identity Provider”. What that means is that the Single Sign On company’s primary goal is to say, “I’m pretty sure this is John Doe” and you have to be OK with that. Remember, your login page with it’s password…. that’s exactly what it’s doing as well. It’s saying, “this is John Doe, because he has the password you gave him”. There are 2 primary ways this is done with SSO.
1. Social Media: In this case, “This person is logged into John Doe’s facebook (or gmail or linkedin or whatever you pick) account, so we’re pretty sure it’s John Doe who’s trying to log in to your system.
2. Private Database: In this case, you’ve used a database at Auth0 which will hold an identity for the user and a password you assign. the response to a login will be, “This is John Doe, because he’s in your DB and has the password you gave him”.
Now…. here’s where people get confused.
Your databases generally have a user table and there are actually 3 critiera to login:
- A login name that exists in the table
- A matching password
- an active status
That last part is the “Authorization”. That’s really up to you with SSO. You decide if they’re allowed in. So, your user table still exists, but it is like, “John@Doe.com is an active user with permissions to do XYZ”. Auth0 (or whatever identity provider you use) will basically say, “Yeah, this is John Doe, because you said that, if a user is logged into their gmail account under John Doe, then we should believe the user is John Doe”. The password is no longer necessary in your own database. You’ve “linked” your employee’s identity to his Gmail or Social Media or even the password you set in Auth0. They have Identified the user…. “Authenticated” them. However, it’s up to you and I to decide if they’re allowed in the door, and if they come in, what they can access.
So, what’s the point, really?
For our customers (the small/midsized businesses we develop for), it enables them to sign into their Gmail account, and click a link to a PO or an inventory report and just “go”. No more logins, no remembering more passwords, etc… For us, it means that we’re no longer responsible for maintaining passwords (encrypted or no, it’s a liability). With Auth0, we can ALSO add some meta data to the account. So, if john@gmail.com is fired, we can set a value like this: app_metadata.youWereFired = true . Then, for any login where it says, “hey, this is john doe, can he come in?”, your system sees that and boot him out. So, a single point can block the guy from all systems using Auth0 for authentication. Again, it’s a liability issue.
Now we can get to a bit more nitty-gritty. How do you get started with all this?
Well, you’ve probably already got your own login page and Auth0 (or any of these providers) will want you to redirect users to their login page. You login there and then it redirects the user back to your system. It sounds great, but we all know how freaked out a user becomes when you change things on them, especially corporate intranet systems, where employees need to login to pull a pick-list so they can load a truck for deliveries or a salesman will need to put together a quick quote for a client. Anything “weird” will be attacked. And you simply can’t all those redirects without causing a stir. So, we start out by handling it server-side. The client won’t even know.
In this case, it’s actually fairly straight forward.
To get things started, you need to build an internal database in Auth0. So, from your current login page, when someone logs in, you authenticate them as you normally do, by recving a post from a webpage and looking up their username and password in your own application’s database. However, you now add an additional step: Create a user in the Auth0 database. Just use all the data in their current user account for your system. Since they’re logging in, at that point you actually have their password unencrypted, so you can set that as well.
Next, you’ll need to alter your management page, where you add/edit users. Right now, you’re just growing this Auth0 db from the login page, but that’s going to stop once they’re all in there. But you still want to ensure you can control who has access to this system and what they’re authorized to see. So, you are going to set up add/edit for users in your system (you should never delete anything. just set an app_metadata value to deleted and ensure you use that as a login criteria)
Finally, you’ll need to remove the auto-add feature and change it to an authentication feature. So, where you were using your own system to authenticate, you simply call Auth0 and say, “hey, here’s username x with password y. Is he who he says he is?” And you’ll get a response with the entire account (or “Nope, not him”). Then, from Auth0’s app_metadata, you’ll want to look at “global variables”, things that will affect all users of all applications, like “youWereFired”, to see if you should immediately boot them out. If not, then you look in your own user table to determine they can come in and what they can see. If you want, you can keep it all in Auth0, but since you’ve already got it in your system, it’s probably best to keep anything “specific” to your system in your own system.
Seems like not a big return for quite a bit of work and risk, right? Well, it’s actually more than that. You see, once you’ve done this, you can do the exact same thing to all your other applications, and the users will match up. That’s great, but still…. what’s the difference between this and just having your own external database with an API? Well, not much. But with your own API, it would end right there. With Auth0 (or any SSO provider), this is where the money comes in.
You can tell Auth0 that your application will “accept” identities from another Provider, like Gmail. Now, what that means is that your application will have your own “auth0” database that you built, and ALSO their gmail account, if it is the same email as in your Auth0 database, or IF you link them (I’ll get into that later). So, if their username is john.doe1234 and the password is KS(#*&@J(X for your database, but their gmail account is jdoe@gmail.com and you don’t have any idea what their password is, when they login to your DB, you can pass those credentials over to Auth0 and they’ll actually come back with the identity of the gmail AND the linked account with it’s permissions. (so, if they’ve been fired, they’ll “authenticate”, meaning you’ll know who they are, but their “youWereFired” meta tag will be set to true, so they aren’t “authorized” and will get turned away)
Ok so far? We’ve now taken an old existing system and set it up so users can use their gmail account (or whatever you’ve allowed) to authenticate as well as a custom Auth0 database with settings you’ve set and only you’ve set.
What’s next? Now we go all-out Single Sign-On. That’s what we all want, right? Kinda? Well, at this point, you’ve got options. If you’re reading this, you’ve probably got more than one system and you have another one in the works. You can now start on the new one, and all your user accounts will be handled for you by the legacy system you just modified. Forget user accounts and account managers entirely. You can now use the little redirect login page from Auth0 and manage your authorizations with their encrypted tokens.
So, here’s the path:
1. Build your database
2. Modify your user manager
3. Enable Auth0 authentication (with or without social media account links)
4. Enable Auth0 authentication on all new applications
The final path will include handling the client-side authoriziations by using encrypted tokens in your user’s local storage and automating the logins with fast requests and callbacks from Auth0 so a user who has logged in to one system will appear to be already logged into all the other systems.
The way that works is with these Authorization and identity Tokens. The user goes to a webpage on your app where they are required to have logged in, they get kicked out and sent to the Auth0 login page for your company, that webpage has its own localStorage and it checks to see if the user is authenticated, if so, it redirects the user directly back to your app with a token in the querystring, which you can then use to pull the entire user account and stick it in your own app’s local storage, then send the person right back to where they came from, all in a second or two.
process of seamless auto-login:
1. your app gets a call for http://yourapp.com/mysecretpage
2. your app looks for id_token, the auth_token and expiration date. So, if you’ve got all those, it can decrypt the id_token and you’re good to go.
3. if the token wasn’t there or was expired, your app redirects to the auth0 login page for your account with a call-back page defined to return to a callback page.
4. The auth0 page looks in its localStorage to see if there’s a good auth_token. If so, it simply redirects the browser right back to the callback page on your app, but in the URL QueryString, it has a token that you can use to call Auth0 for a full profile with Ajax. And then, move you back to where you came from, fully authenticated.
Next Chapter: The C# code for WebAPI