3

We are building a multi-tenant application which will be hosted in multiple data center (Azure) across the world.This application will also expose API (not just MVC web application).

To handle authentication/authorization, we were planning to implement Owin OAuth but then we came across 'Thinktecture IdentityServer3' which suits our bill.

Also, if a tenant has account in any regional instance (like 'NA1.ourwebsite.com'), not only should he be able to login through 'NA1.ourwebsite.com', but he should also be able to login through a centralized instance/identity server 'ourwebsite.com'.

NA1.ourwebsite.com - North America instance

EA1.ourwebsite.com - East Asia Instance

Currently, we have different databases for each tenant and its user information also lives in their respective database.

I am not sure how one application can have multiple identity servers (I don't know if I have to chose federated servers).

SalesForce.com does exactly the same thing, but I don't know how. Can anyone help me in this?

Thanks in advance.

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
Pragmatic
  • 3,093
  • 4
  • 33
  • 62

1 Answers1

7

To handle authentication/authorization, we were planning to implement Owin OAuth but then we came across 'Thinktecture IdentityServer3' which suits our bill.

It does indeed. The Thinktecture IdentityServer3 is an implementation of OpenID Connect, and OpenID Connect is OAuth with the addition of an "identity layer." You can still use OAuth for authorization (access to protected resources), because the OpenID Provider typically returns an access_token. It also returns an id_token for authentication (verification of identity).

Also, if a tenant has account in any regional instance (like 'NA1.ourwebsite.com'), not only should he be able to login through 'NA1.ourwebsite.com', but he should also be able to login through a centralized instance/identity server 'ourwebsite.com'.

That is a use case that OpenID Connect enables. You will be able to give the end-user a choice of whether to login with NA1.ourwebsite.com, with ourwebsite.com, or with any other OpenID Connect provider. For instance, I am able to sign into the same StackExchange account using several providers.

My stackExchange logins include StackExchange, Google, and Microsoft.

Of course, the end-user needs to associate each OpenID Connect identity with their account at your app. Sometimes your app can figure this out automatically based on the OpenID Connect claims (e.g. email) while other times the end-user has to associate the login manually. E.g.

Logging in with a new account to StackExchange.

Currently, we have different databases for each tenant and its user information also lives in their respective database.

There are a variety of approaches you could take moving forward. You will want to differentiate the user information that is relevant only to your app from the user information that is relevant to authentication. You cannot reasonably expect all OpenID Connect providers to store all the user info that your app requires. In regards to user info, it will only be able to verify your user's identity and provide profile information that your user already stores at the provider (e.g. stuff that is in their Twitter account.)

I am not sure how one application can have multiple identity servers (I don't know if I have to chose federated servers).

This is kind of like how one airport can accept multiple forms of identification: birth certificate, electricity bill, passport, drivers license. It is hard to understand but once you grok that the id_token is like piece of trusted identification you can start to appreciate it. As real world example is a birth certificate. In this case, the government is the identity provider and the birth certificate is the id_token. An application get to choose what identity providers it accepts.

SalesForce.com does exactly the same thing, but I don't know how. Can anyone help me in this?

In addition to salesforce.com, as noted above stackexchange.com also does it. The diagram from the OpenID Connect specification will help a bit.

+--------+                                   +--------+
|        |                                   |        |
|        |---------(1) AuthN Request-------->|        |
|        |                                   |        |
|        |  +--------+                       |        |
|        |  |        |                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|        |  |  User  |                       |        |
|   RP   |  |        |                       |   OP   |
|        |  +--------+                       |        |
|        |                                   |        |
|        |<--------(3) AuthN Response--------|        |
|        |                                   |        |
|        |---------(4) UserInfo Request----->|        |
|        |                                   |        |
|        |<--------(5) UserInfo Response-----|        |
|        |                                   |        |
+--------+                                   +--------+
  1. The RP (Client) sends a request to the OpenID Provider (OP).
  2. The OP authenticates the End-User and obtains authorization.
  3. The OP responds with an ID Token and usually an Access Token.
  4. The RP can send a request with the Access Token to the UserInfo Endpoint.
  5. The UserInfo Endpoint returns Claims about the End-User.

The OP is an OpenID Connect Provider. I think that is what you mean by "identity servers." You can accept tokens from whatever providers your app decides to trust. The end-user gets to choose which provider to use when logging in (you will often see this as a choice to login with Twitter, Facebook, Google, Microsoft...). One of those choices could be ourwebsite.com.

The RP is the relying party, which in this case is your application. It is called the relying party because it relies on the various OPs for authentication, authorization, and some user profile storage.

Steps (1) to (3) above are almost exactly the same as the OAuth authorization flow, in which the end-user signs in to the provider of choice, and the provider responds with a token. The difference with OpenID Connect is that in step (3), the response typically contains an id_token in addition to an access_token.

The access_token represents the end-users authorization. It is an OAuth beaker token. Your app includes it in requests for protected resources. Those protected resources could include user info stored at the OpenID Connect provider. See steps (4) and (5).

The id_token represents the end-users authentication and contains claims about both the end-user and the Open ID Connect Provider. The iss claim identifies the OpenID Provider, the sub claim uniquely identifies the end-user, the aud claim identifies the Relying Party (your app). Other standard claims include the name, given_name, family_name, middle_name, picture, website, email, phone_number of the authenticated end-user.

The most important ones for authorization are the sub and the iss, because the combination of those two uniquely identifies the login.

OpenID Connect is complex and takes some time to fully appreciate. Your persistence will pay off because it perfectly matches your use case. The Thinktecture IdentityServer3 looks like a solid option. Another similar one to evaluate is the AspNet.Security.OpenIdConnect.Server.

References

OpenID Connect in a nutshell. Written by one of the authors of OpenID Connect, this post contains two particularly helpful sections: "Making an OpenID Connect request" and "Receiving an OpenID Connect response."

OpenID Connect Core 1.0 incorporating errata set 1 One of the specification documents that contains the helpful diagram posted in this answer.

The OAuth 2.0 Authorization Framework: Bearer Token Usage An OAuth RFC that explains how to use the access_token in a request for a protected resource.

Community
  • 1
  • 1
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
  • 1
    Thanks Shaun for the info. But does that solve my problem (which I described above)? Other than that, Could you provide some details on 'How it is different that IdentityServer3' – Pragmatic Sep 05 '15 at 15:41
  • 1
    Would be great if you can help me solving this use case (once you have time). Have a nice weekend :) – Pragmatic Sep 05 '15 at 16:55
  • Re: how is it different from IdentityServer3, it might just be the ASP.NET version. The AspNet.Security.OpenIdConnect.Server code uses ASP.NET 5. – Shaun Luttin Sep 06 '15 at 00:35
  • Also, IdentityServer3 has a whole ecosystem and offers tons of abstractions (client apps/users stores). AspNet.Security.OpenIdConnect.Server, on the other hand, offers a low-level approach and you need to implement a few things like the authorization endpoint if you want to support interactive flow. IdentityServer3 has tons of default views, but is much harder to customize. IdentityServer3 is more nub-proof, but our server is much more flexible. (Thank you to PinpointTownes for the sound byte :-) – Shaun Luttin Sep 06 '15 at 14:34
  • 1
    Hi Shaun, Thanks for the information. We have decided to go with IdentityServer 3. Can you help me in following queries - The application we are building has it own user base. My Single Page application is the primary application (or say owner application) for these resource. So, I feel, if user goes to my SPA, it should not be using OAuth/Open connect. OAuth/Open connect is meant for the other applications (which re not the owner applications for these resources). I guess, this is how Google works. It never uses OAuth when u log in to gmail, but it uses OAuth when u use it in stackoverflow. – Pragmatic Sep 09 '15 at 07:45
  • When the user goes to your SPA, you can the Resource Owner Password Credentials flow. Here is an partly done example. http://erdnase.azurewebsites.net/relying-party.html The username is `shaun` and the password is `Testing123!` – Shaun Luttin Sep 09 '15 at 14:48
  • 1
    Shaun, Do you really recommend to go with OAuth/Open Connect for my primary application? I don't think Google works this way. All google's app (gmail, maps) etc. seems to be working differently and sharing cookie among them. But when we use google credentials on stackoverflow, only then they use OAuth. – Pragmatic Sep 09 '15 at 14:54
  • 1
    And to clarify further this primary application is the application that is use to create userbase (add/delete user, create/update password policy, and all the other resource management). I feel, other applications should ask for id_token and access_token to access these resources. – Pragmatic Sep 09 '15 at 15:16
  • @Pragmatic You might be exceeding my knowledge here and I do not know how Google works. I will give you my opinion anyway :) Once someone has signed in with your application, I do not see the difference between issuing a cookie and issuing an `access_token` and `id_token`. Maybe you can help me out here. :) – Shaun Luttin Sep 09 '15 at 15:46
  • From reading up some more, it seems that Google etc might use Cookies because, "Tokens stored in local/session storage ... can't be accessed from different domains (even if these are subdomains)." What you can do in this case is to augment the token with a Cookie that works cross-sub-domain, so to speak. https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/ – Shaun Luttin Sep 09 '15 at 16:03
  • Hi Shaun, I am very close to finalize design for my use case. I will share with you once it is done. In the meanwhile we are stuck in one more scenario which I have asked here http://stackoverflow.com/questions/32537284/how-to-protect-mvc-pages-and-webapi-residing-in-common-project-using-thinktect Please share your thoughts on this. – Pragmatic Sep 12 '15 at 09:36