IdentityServer4 + Asp.Net Core Identity - Map Identity to application database user
Asked Answered
L

3

18

I am trying to implement an IdentityServer4 with Asp.Net Core Identity. I want to use IdentityServer4 as centralized authentication/authorization point for APIs using always the same identity. So the idea is to store the Asp.Net Core Identity stuff in an SQL Database which serves as the identity store.

The question now is how to map the centralized identity to application specific data. I want to use same identity user in several applications, but in each application the user has other related entities, roles etc.

I read through the documentation of IdentityServer4 but could not find anything related to a proposed structure.

As I understood, you somehow map the identity id to your local application user. Basic data like firstname etc are stored in the centralized identity store and application specific data is stored in the application specific database. So you would not save firstname etc in the application specific db right? In the every request where you need user specific data will query the identity server to get information/claims? What about registration process?

Does anybody have a clear structure setup which could be used to understand the whole setup? (Separation like Asp.Net Identity Provider, IdentityServer4, Protected Api.)

Lumbye answered 4/9, 2017 at 13:15 Comment(0)
F
7

So you would not save firstname etc in the application specific db right?

Yes, User specific properties should go into the user profile and should be saved in the user store(database) of IdentityServer. Application specific user data should be stored in the application store.

In the every request where you need user specific data will query the identity server to get information/claims?

Not necessarily, The user specific data can be included in identity token as claims. The claims will then be stored in a cookie as authentication ticket. For each request, those claims(stored in cookie/s) are available via User property of the controller

var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;

You can store and query application related user data stored against a user Id(sub claim can be used as a user Id).

If you need a lot of user-specific data in an application it is not optimal to include everything in identity-token and it is unlikely that you will need those for each request. So when you need extra information you can query UserInfo endpoint of identity server. Just include basic information you need to identify a user in your identity token.

What about the registration process?

Registration is a completely separate workflow that there is no involvement with identity server. You just need to save the user to identity store(probably using asp.net identity). Of course, you can host the registration controllers along with identity server, so that identity-related stuff is physically on the same server. You can also just write to IdentityServer user store from anyplace you host your registration process(e.g. A separate admin UI, or From a workflow involving email verification, manual approval etc...)

Farmyard answered 25/1, 2019 at 9:21 Comment(1)
Thanks for the explanation!Lumbye
V
3

To customize what you store in Asp.net Core Identity, you need to use services.AddIdentity<ApplicationUser, ApplicationRole>. ApplicationUser and ApplicationRole are extending IdentityUser and IdentityRole. This way you can make it store any extra info you want.

Then to return the extra info you need to create a ProfileService that implements IProfileService. With this service, you can add any extra information to claim tokens.

You need to register this service as

services.AddSingleton<IProfileService, ProfileService>();
builder.AddAspNetIdentity<ApplicationUser>().AddProfileService<ProfileService>();

You can register the user with extra info like below:

var user = new ApplicationUser
            {
                UserName = Username,
                Email = email,
                ExtraInfo1 = "Hello",
                ExtraInfo2 = "World"
            };
await _userManager.CreateAsync(user, "SomePassword");
Viridi answered 24/1, 2019 at 17:34 Comment(2)
Do you say that mixing application specific and identity data is a good idea?Twiddle
It all depends how complex it will get. Personally, I just add a column with a foreign key. And with that foreign key, I can just query all other tables as necessary. For example, you can add a column called MemberId to your ApplicationUser, and this can reference to your Members table. And from there you can create all the complex table structure your app needs.Viridi
M
1

With OpenId you have default set of claims associated with user. So any client application can access those claims. Make sure each client has openid and profile scopes assigned to them. Otherwise client application not able to access the users basic details.

In Asp.Net Core application you can access those claims in controller using User property.

Macassar answered 25/1, 2019 at 4:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.