Reputation: 3127
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.
Upvotes: 3
Views: 1682
Reputation: 141662
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.
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.
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-----| |
| | | |
+--------+ +--------+
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.
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.
Upvotes: 7