0
Frontis2 created
- ABP Framework version: v7.1.1
- UI type: MVC
- DB provider: EF Core
Currently am trying to add an external login, using Azure Active Directory. The purpose of this external login, is to be used by administrators only.
As described in the community blog post, I did the following... Note the CustomOpenIdConnectEvents class...
private void ConfigureExternalProviders(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication()
//Omitted other third party configurations
.AddOpenIdConnect("AzureOpenId", "Sign in with Microsoft", options =>
{
options.Authority = $"https://login.microsoftonline.com/{configuration["AzureAd:TenantId"]}/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.ClientSecret = configuration["AzureAd:ClientSecret"];
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("email");
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
options.SignInScheme = IdentityConstants.ExternalScheme;
options.EventsType = typeof(CustomOpenIdConnectEvents);
});
}
And here is the CustomOpenIdConnectEvents class:
{
[UnitOfWork]
public override async Task TokenValidated(TokenValidatedContext context)
{
await base.TokenValidated(context);
var userManager = context.HttpContext.RequestServices.GetRequiredService<IdentityUserManager>();
var userEmail = context.Principal.FindFirstValue(ClaimTypes.Email);
var currentUser = await userManager.FindByEmailAsync(userEmail);
if (currentUser != null)
{
var adminRoleName = "admin"; // Replace with your admin role name
var isInRole = await userManager.IsInRoleAsync(currentUser, adminRoleName);
if (!isInRole)
{
await userManager.AddToRoleAsync(currentUser, adminRoleName);
var identity = context.Principal.Identity as ClaimsIdentity;
identity?.AddClaim(new Claim(identity.RoleClaimType, adminRoleName));
}
}
}
}
The code itself is working. However with the following issues:
- The user must log out and log back in, before he is admin
- I think this is because the user account only exists after he hits "register".
- Am not quite sure if finding the user based on the mail-address is save. However, finding by claim does not work.
var currentUser = await userManager.GetUserAsync(context.Principal);
Concrete: How can I make sure users are automatically administrator? Preferably the registration form should be skipped.
1 Answer(s)
-
0
Hi,
You can create a user if it doesn't exist:
[UnitOfWork] public override async Task TokenValidated(TokenValidatedContext context) { await base.TokenValidated(context); var userManager = context.HttpContext.RequestServices.GetRequiredService(); var userEmail = context.Principal.FindFirstValue(ClaimTypes.Email); var currentUser = await userManager.FindByEmailAsync(userEmail); if(currentUser == null) { // create a user } var adminRoleName = "admin"; // Replace with your admin role name var isInRole = await userManager.IsInRoleAsync(currentUser, adminRoleName); if (!isInRole) { await userManager.AddToRoleAsync(currentUser, adminRoleName); var identity = context.Principal.Identity as ClaimsIdentity; identity?.AddClaim(new Claim(identity.RoleClaimType, adminRoleName)); } }