Fairly new to Razor Pages. My IndexModel is a bound List<CLPost>
that has a 'CreatedByUserId' included. The Identity information is in another DBContext entirely so I cannot setup an entity relationship to IdentityUser. What would be the best way to return the CreatedByUser's full name? Thanks!

- 908
- 2
- 8
- 20
-
1The best way would be to use one context and one database. Why has Identity got a separate context? – Mike Brind Nov 09 '18 at 15:58
-
1Or write code to use both `DBContext`s? Doing this will probably be less efficient (it will use multiple queries) but in some cases it may suffice. – Peter B Nov 09 '18 at 16:02
-
@MikeBrind One context is for the application and the other is for the central user store. Is there a better way to do a central user store to share across applications? Again, fairly new to .net core and razor – Fraze Nov 09 '18 at 16:04
-
1That detail would have been useful as part of the question. If you have to use two different databases, you can either write code to use both contexts as @PeterB said, or you can use a Query Type to represent your objects, stored as a view: https://www.learnentityframeworkcore.com/query-types – Mike Brind Nov 09 '18 at 16:11
-
Thank you both I ended up doing it with code. Derived a VM from the base class and queried for user info from the UserManager
– Fraze Nov 09 '18 at 17:35
1 Answers
It's actually a good thing to keep Identity seperated from the business context. This way you'll have a clear seperation of concerns.
The problem you've encountered is that the information is not part of the context.
Mixing the two contexts is not going to help you and querying both contexts is not the solution. So what's the easiest way to solve this? Make sure that the information becomes part of the context.
In the situation where data is inaccessable, you'll need to make a local copy of the data you need. So in case you want to show a username on a report, you'll need to create a local copy of the user including the relevant information.
Sounds redundant? Well it isn't. In fact this is how Identity works. When you login with an external provider, like Google, a local copy of the user is created in the AspNetUsers table. Redundant? No, because you don't have access to the source.
Same here, sure you can have all apps to access the user store, using the UserManager. But suppose you can't and most certainly, this is not how you would want it. Only one app should be responsible for Identity.
Please note that the information of the current user is available in the claims. It's important to realize that e.g. User.IsInRole
is in fact looking at the role claims of the User, not the AspNetUserRoles table.
For the current user make sure all claims are available. As you need information from other users, you'll need to store it in the business context. You can either choose some strategy to read information from claims when the user logs in, or simply add functionality to maintain the user information.
Bottom line is that you'll need to create a User table in the business context that contains the information you need for reports.
And since it's then part of the same context, you can simply access it with one query. You can add a column to reference the current identity subjectId, the sub
claim in OpenIdConnect. In order to match this with the current user.
Then you can add authorization based on this sub, without an actual relation between the both contexts and user tables.
Please also read my answer here for some more thoughts about this: Is claims based authorization appropriate for individual resources