简体   繁体   中英

Change user authentication privileges using .NET Core 3.0 Identity

I'm questioning myself the best way to extend Microsoft Identity to implement the following situation:

I have a domain were my users can be: Athletes, Coaches and Administrators.

When a user is registered is automatically assigned as an Athlete and the Athlete Entity is created (It is created in parallel with the AspNetUser.)

Because the Commands and Queries and user properties of the different actors *Athlete, Coaches and Administrator) are way different inside the domain, make sense to create separate entities for them.

When the user login he can select in the UI which "role" (not related with Identity role/claims) he wanna access the system and will see only the UI components related to that position.

So the question is how to switch between different "roles" and store this information in the login session:

I'm using claim/policies to authorize the user, my idea at the moment is to add/remove claims on the fly when the user switches between "roles".

This would work to authorize the user between the different Policies on each API routes. However the domain must know which "role" the user is acting at that moment.

Should I create claims with names Administrator, Coaches and Athlete and insert / remote then when the user switches roles?

Is there a more elegant way how to tell the domain which position the user is acting different from inserting removing claims on the fly?

Your design is too complicated for what you are trying to accomplish. I guess you know this, because that's why you've come here to ask this question.

My advice is not to use claims for this kind of design. It's the wrong solution for this problem. A resource-based authorization solution would seem more appropriate.

The design can be quite simple in that case.

I suggest you setup a seperate Identity context and a seperate business context. The tables may exist in the same database, just don't add relations on database level and don't mix the context models.

The Identity context is for authentication, which is completely out of scope for the business context. This also means that the Identity user has nothing to do with a business entity, such as employee, customer, coach, etc. It only allows a user to login.

But what good is a user that has no relation to the business context? That's why you should create a 'person' table, or in your case three tables, in the business context. Add a column to each table where you can store the UserId.

I said 'person' because these aren't actually users. Suppose the system is available to coaches only. In that case athletes exist, but have no linked login user.

Now, the UserId is in fact a claim that's added by Identity to uniquely identify the user. In oidc this is the sub claim, but you can use whatever claim as long as the claim type is a constant and the value is the unique userid from the aspnetusers table.

With this Id you can link the login user to a business context entity (person). On user registration add a record in the appropriate table(s) and save the Id of the user in the UserId field. The very existence of this record means that the person is an athlete, coach and/or administrator. Revoke access to functionality by removing the record. And as you can see, there is no need for a database relation. The value of the user id suffices.

Since the Identity context technically has no knowledge of the type of business user, you'll have to figure out how and where to add the code to insert the business context entities.

In your UI add a dropdown where the user can select the available type, based on a joined select from the business 'person' tables. Each entry means that the 'role' is available for this user.

You can also use advanced authorization by using policies and defining requirements, as shown in the earlier mentioned article of resource-based authorization. Where you can check the UserId instead of the name, something like:

if (context.User.Identity?.GetUserId() == resource.UserId)
{
    context.Succeed(requirement);
}

Now Identity is used for authentication, while authorization (at least this part) is handled by the resource. Which is a good thing since the resource knows what the user is allowed to do.

For more information and thoughts take a look at some of my other answers. And while this may be out of scope of your question, I can recommend the article Identity vs Permissions and the follow up PolicyServer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM