IdentityServer4: different user types in different

2019-08-16 18:24发布

Current situation: I have an application with 3 WebAPI projects (let's say API A, B, C). Each has token-based auth (based on OAuthAuthorizationServerProvider). There are 3 user types (let's say Type 1, 2, 3). Each user type is stored in the separate database table;

  • "API A" used by mobile clients ("Type 1" users)
  • "API B" used partly by mobile clients ("Type 1" users), partly by web client (angular application, "Type 2" users)
  • "API C" used by web client ("Type 3" users)

Also,

  • "Type 1" users can get token from "API A" and exchange it to another token from "API B" in order to get access to "API B" resources (some controllers in "API B" used by "Type 1" users, others - by "Type 2" users)
  • "Type 2" users have 2-step authorization
    • They use login and password to get a token with "restricted access" to a single controller in order to choose some value from it
    • Using the previous token and chosen value they exchange it to "full access" token

I'm planning to migrate from the current authorization scheme to IdentityServer4. So, I have a few questions:

Main question:

  1. How to authenticate 3 different user types in 3 different database tables by a single endpoint (server/connect/token) with single IdentityServer4 instance?

Additional questions:

  1. How can I implement 2-step authorization for "Type 2" users?
  2. What can you advise in my situation?

Thanks!

1条回答
何必那么认真
2楼-- · 2019-08-16 18:51

For IdentityServer there is only one type of user that needs to be authenticated. So all users should be moved to the same table (how to migrate is another question). If moving the users to one table is an issue, then IdentityServer may not be the right tool to implement security. Though it is possible to maintain seperate tables by implementing a custom user store. Two factor authentication can be enabled per user. You can use extension grants to implement custom grants.

The whole purpose of security is to protect your resources: the api's. In IdentityServer the resource name is a logical name for the functionality that can be split in several scopes, where a scope is a certain functionality.

Api1 can be the resource with multiple scopes (e.g. Api1.Read and Api1.Write) or simply Api1. But Api1, Api2 and Api3 can also be part of the Api resource where Api1, Api2 and Api3 are in fact scopes. In your case Api1 could be the resource with Api1 as scope.

To make it possible for the user to access a resource you'll need a client application, though you can have many clients that can access the same resource. In order to support the different types of clients, there are multiple grant types that can be chosen from.


IdentityServer allows you to configure the complete picture.

Let's assume there is one client that has access to the different Api's, where each Api is a resource/scope.

The client needs to be allowed to access the Api's on behalf of the user, because the client can't access the resource without user.

So the client should be allowed to use certain scopes, where the scope needs to be requested by the client. Without this, a client can't access a resource. Suppose the client is configured for Api1 and Api2, but only Api1 is requested by the client. Then Api2 and Api3 are not reachable.

This is all part of the authorization at top level. Now it's time to involve the user. When the client accesses the api then the api knows which user made the request (as sub is part of the access token). But that is not enough to grant or deny access.

So you'll need something to authorize the user. There are many options on how to implement this. Take a look at the documentation.

Consider a simple implementation where there are three policies. And each policy makes sure that only the matching type of user has access.

Then the actual question is, how to distinguish the type of user?


You can add a claim in the UserClaims table. Let's assume ClaimType is UserType and value is 1. In the resource add a policy that checks for the claim UserType and the required value.

In order to let IdentityServer add the claim to the access token, make sure the claimType is part of the scope (or ApiResource when multiple scopes are configured and need the claimType).

By adding the claimType UserType to the Api_ scope, means that when accessing the scope, the claim must be included. IdentityServer tries to limit the number of claims in the access token by filtering on requested claims only.

When the user accesses the Api_, then the claim should be part of the access token (assuming the claim is set for each user, otherwise the user has no access at all). You can repeat this setup for the other api's (scopes).

In this case, I think this is an acceptable solution. Other options are authorization at a lower level (resource based) or outsourced, like PolicyServer.

Please note that because of SSO it may be possible that the user is authenticated by other clients as well. But since access is granted to certain types of users only (as part of the policies), you can prevent other types of users to access the resources that are not meant for them. You can prevent this behaviour by disabling automatic login.

查看更多
登录 后发表回答