What is authentication and what is authorization. At first I didn't know there was a difference. You have a user and a user has roles. Simple as that. It all started after I read the interesting article that Dominick Baier wrote. I can highly recommend anyone to read it.
Authentication vs Authorization
While in older systems all data is within the same context, using membership you don't have a problem. The problems start when newer security has to be implemented. Where contexts are not in the same database and contexts are shared by multiple applications.
For that you'll need to maintain seperation of concerns. The authentication / authorization should be seperated from the business logic. Meaning that you cannot use the same user table for both contexts.
At first this seems strange, but when you think of it it makes sense. The identity user is not the business user. But as authentication is not authorization, should these contexts also be seperated?
I've been struggling with this for a couple of years. I just couldn't put my finger on it. But recently I've managed to find an acceptable answer for myself. I want to share my thoughts with this blog. Perhaps it saves others some time.
DefinitionAuthentication is about WHO the user is. This is free of any context as it simply tells about the identity of the user. Translating this to claims, (Identity)Claims are used to model the identity of the user. Authentication is done by a trusted IdentityProvider. Which has one task only: to identify the user.
Authorization is about WHAT the user is allowed to do. This depends on the context. E.g. in some countries you are allowed to consume alcohol at the age of 18. While in other countries you'll have to be at least 21 or are not allowed to consume alcohol at all.
Think of authorization as a set of rules, like:
18+: allow when user is older than 18 (claim: DateOfBirth).
Use car: allow when user has a drivers license (claim: LicenseNumber).
So authorization is in fact a set of business rules. Where (Identity)Claims and business information can be used as input. Authorization should be done close to the resource. The authorization context is optional when authorization is done entirely with rules.
RolesThe most confusing part about authentication and authorization is roles. Is a role part of authentication or part of authorization? It would help if it is part of the identity, because in that case you can simply add them as claims. But this gives headaches when you want to update or remove them.
When we explore the WHO question, then we could say, someone is a nurse or a patient. This seems true, but what if the user is a nurse in one hospital and a patient in another hospital, or even the same hospital? Seems that roles are not as universal as e.g. having a drivers license or a certain profession.
I mentioned profession, because you can be a journalist (as well as a nurse) which doesn't depend on a context and doesn't tell anything about what the user is allowed to do. So is profession a role? No, as profession is part of the identity. It tells something about who the user is, so add it as (profession) claim, not as role.
Can we conclude that roles are part of authorization? Well, it doesn't tell much either about what the user is allowed to do. Being a nurse or a patient can also be part of the business context instead of being a role in an authorization context.
Question is, when is something part of the business context? I follow this rule: when a report needs to show the information then it should be part of the business context. Take user name for instance, this is part of the identity. When I need to show the user name then I will need to include it in a user table that is part of the business context. You may argue that the information is redundant, but actually it isn't. As the information is not part of the same context.
This places roles outside the authentication context and also outside the authorization context. But it doesn't seem to fit right entirely. As roles can be used to manage and group permissions. So roles can exist in both the authorization context as the business context. The first to add permissions to roles and the second to add roles to users. However, when a role is not part of the business context, add it to the authorization context instead.
DesignKeeping seperation of concerns in mind we can define three seperate contexts:
Identity context: users + userclaims. For authentication only. Application independent.
Authorization context: [optional] users (id = sub claim) + per application: roles+permissions, etc. In seperate 'local' databases or in a central database. For authorization only.
Business context: users (Id, Name, 'foreign key' sub claim, without the actual database relation as the table is outside the context) + roles, teams, profile, settings, etc. Linked to the sub claim value when users table is omitted.
In order to keep the users table in the business context up-to-date, periodically refresh the values. You can for instance update values when the user logs in after x time. Or once in a while query the Identity Context (using the API) to request user information (using the identities User Info endpoint).
In all contexts there can be a users table, but they all have a different meaning and contain other information. So there is no redundant information.
Authorization takes place inside the application and is based on the business rules (policies) and authorization information from the authorization context.
As a final remark, when the current system requires role claims (like for
[Authorize("role")]) then you can read (from cache) the role / permissions on each call and add these to the claims collection of the current user (claims transformation).
Keep authorization close to the resource (api / website). Because that is the place where the business rules are implemented. And that's the place where you can store and update permissions, etc.
Keep a seperation of concerns when it comes to authentication and authorization. Authentication tells you who the user is, and authorization tells you what the user is allowed to do. Don't mix these two.