C
C#4mo ago
Ragtox

Local user accounts with Entra External ID in Blazor WASM BFF application

Dear colleagues, I am currently researching our options to move away from local identity user accounts using Microsoft.Identity and EF Core. Currently, we have landed on Entra External ID as one of our options, but this question "shouldn't" really be vendor dependant. We would like to still store a local "user", this local user will be used for permissions, owned data, management by admins, etc.. I have two question: - How/when should we create this local user account? - Are the simple tables User and UserClaims enough, or should we use Microsoft.Identity but only allow external logins? Currently I have considered the following options: - OnTokenValidated event from the OpenIdConnectEvents class - Some middleware that checks every authenticated request if a local user exists for the current principal In my opinion, it would be cleaner to instead override the default /signin-oidc route and handle it at the end of the sign-up process here, but it seems that you're unable to configure this route without completely copying the source code. If anybody would have any experience implementing this and would like to share their toughts and/or interesting reading material, would be great. Thanks!
3 Replies
Ragtox
RagtoxOP4mo ago
Oh, I also forgot to mention that my current PoC uses the Microsoft.Identity.Web & Microsoft.Identity.Web.UI packages And also some sample code from how I currently use the OnTokenValidated event. (This is just a PoC of course, so not a lot of validation/fallback stuff is happening)
options.Events = new OpenIdConnectEvents()
{
// Perform logic to store user in database
// Should probably check if a claim is present, "newUser" or something
OnTokenValidated = async context =>
{
if (context.Principal != null)
{
try
{
var dbContext = context.Request.HttpContext.RequestServices.GetRequiredService<IdentityDbContext>();
var oid = context.Principal.FindFirst("oid")!.Value;
var idp = context.Principal.FindFirst("idp")?.Value ?? "";

var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Id == oid);
if (user != null)
{
return;
}

var newUser = new User(oid, idp);

dbContext.Users.Add(newUser);
await dbContext.SaveChangesAsync();
}
catch
{
context.Fail("Something went wrong while persisting this user");
}
}
}
};
options.Events = new OpenIdConnectEvents()
{
// Perform logic to store user in database
// Should probably check if a claim is present, "newUser" or something
OnTokenValidated = async context =>
{
if (context.Principal != null)
{
try
{
var dbContext = context.Request.HttpContext.RequestServices.GetRequiredService<IdentityDbContext>();
var oid = context.Principal.FindFirst("oid")!.Value;
var idp = context.Principal.FindFirst("idp")?.Value ?? "";

var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Id == oid);
if (user != null)
{
return;
}

var newUser = new User(oid, idp);

dbContext.Users.Add(newUser);
await dbContext.SaveChangesAsync();
}
catch
{
context.Fail("Something went wrong while persisting this user");
}
}
}
};
Unknown User
Unknown User4mo ago
Message Not Public
Sign In & Join Server To View
Ragtox
RagtoxOP4mo ago
Wow, how didn't I think of that lol, I was so pre-occupied with moving away from identity that I didn't consider just using Identity but not allowing local account sign-up. Thanks TeBeCo. However, I'm always interested in any other alternatives people have come up with!
Want results from more Discord servers?
Add your server