0
votes

We have an ASP.NET/MVC website that's using FormsAuthentication. As is usual, when the user tries to access a page, and doesn't have a valid FormsAuthentication cookie, IIS redirects him to the login view. When the user does a HttpPost to the login controller, our controller action makes a call to our WebApi webservice, which validates username, password, and customerid against a Sql Server database. If the authentication passes, the controller action sets a FormsAuthentication cookie, and redirects to the page the user had asked for.

Now sales is making noises about "Single Sign-On", though I'm not clear exactly what they mean by that. From what I've read, in the Microsoft World this usually means accessing MS's Active Directory Federation Services.

At this point I have almost no idea how this would work, but before I dig into this too deeply, would it be possible to put the authentication code within the WebApi webservice, where we could choose to validate against the Sql Server database, or against whichever ADFS server was appropriate for the specified customer?

Our problem is that we have I don't know how many thousands of users, working for some hundreds of customers. Many customers will not have ADFS running, and those who do will each have their own ADFS server.

Most of what I see with respect to Single Sign-On seems to involve doing browser redirection to the ADFS server, then redirection back, and looks to be avoiding login at all, if you're already logged in. I don't think we can do that, in our case. We can't know which ADFS server to redirect to, until we hit the database.

So, the question - is it possible to do ADFS authentication entirely from C# code in our WebAPI web service?

(One possible complication - the website itself has zero access to any database. The sole configuration setting in its web.config is the base URL of the webservice. Whatever authentication happens has to happen in the webservice, not in the website.)

2
Always when in doubt how and what SSO is, think of a Google ecosystem. You access any of their apps, you are redirected to a login page on a yet another app and then redirected back with the authenticated user information. This separation allows the identity provider to introduce new features (like two factor auth) without bothering all apps that use the identity provider. And, not true, SSO in Microsoft world is not tied to ADFS. It's just one of options.Wiktor Zychla

2 Answers

1
votes

First of all, "Single Sign-On" (SSO) is not limited to ADFS. It simply means that you type your credentials only once, and then all systems you access automatically "recognize" you; all subsequent authorizations request are transparent. For instance, if you have several web sites using Windows Authentication in your company Intranet (same AD domain), you have SSO: you authenticate once when you log in to your computer, and then your web browser authenticates automatically to these web sites using NTLM or Kerberos. No ADFS in this case.

What ADFS (and "Federation" more generally) allows, is SSO accross security boundaries. In Windows world, a security zone is typically created by an Active Directory forest; everything within this forest is accessible using SSO provided by Windows authentication. But as soon as you leave this zone (SaaS application, web site in another company network), you need another authentication protocol to perform SSO, and these protocols are implemented in ADFS.

Then about your particular problem:

  • What you could do is instead of using FormsAuth, you use AdfsAuth. When a unknown user accesses a page, he would be redirected to ADFS for authentication (using browser redirects as you correctly mention). To know which ADFS server should authenticate your user, you need a way to differentiate them indeed: a list of IP range per customer? a different URL per customer? If you don't have something like this, then the only way is to show them a list of choices such as: "I work for CompanyA", "I work for CompanyB", "I work for CompanyC", "I don't work for any of these companies and want to authenticate using FormsAuth."
  • In this case, what your WebApi web service has to do is: if I know which ADFS server to use, redirect the user there. Otherwise authenticate the user as usual using the database.
  • When you use AdfsAuth for a customer, your database is useless. You can delete all credentials related to this customer.

do ADFS authentication entirely from C# code in our WebAPI

Well it's possible to "re-implement" ADFS in your service, but you won't get SSO if you do that. When you use federation, your redirect the user to the ADFS server of his company. This ADFS server is in the same domain as his computer, so the user gets SSO here. Once again, your users can't get SSO if you authenticate them yourself, because your users are not in the same security zone as your site.

1
votes

When authenticating to multiple identity providers, it is typical redirect to your own STS. So, in this case, you would have www.yourapp.com redirecting to sts.yourapp.com, which redirects to sts.somecustomer.com.

Diagram showing RP-STS

The specific tools to enable such a dataflow is the home realm parameter (whr), and the AD FS Powershell API (to allow IDP maintenance).

Your RP-STS acts as the trust-point for the app, and manages selection of the appropriate IDP. One RP-STS, many IP-STS's. Each of your Customer's IP-STS gets set up as a Claims Provider Trust in AD FS.

As always, Vittorio has already covered the subject better than I could.

Image showing two IP-STSs authenticating to single RP-STS, with a single RP