For context I am coming onto a new project that is using ASPNET Core 7. I am trying to create a custom authorizationHandler for Role management. This part seems to work it fires my custom handler but the user context has no information in it. No claims no nothing. I am impersonating users from the database. After reading the documentation from what I understand the problem is I need to use AddIdentity or AddIdentityCore and add this to services, I found examples of this but never inside this type of inline scaffolding. So adding this inside the configureservices block seems to throw an out of scope error.
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory
1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory
1[Microsoft.AspNetCore.Identity.IdentityUser]': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager
1[Microsoft.AspNetCore.Identity.IdentityUser]'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserManager
1[Microsoft.AspNetCore.Identity.IdentityUser]': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager
1[Microsoft.AspNetCore.Identity.IdentityUser]'.)'
Not sure how I can keep the current "WebHostBuilder" scaffolding and include Identity so my Claims are populated.
//program.cs
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseIISIntegration().UseStartup<Startup>();
})
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<IAuthorizationHandler, RoleHandler>();
services.AddAuthorization(options =>
{
options.AddPolicy("Roles", policy =>
{
policy.Requirements.Add(new RoleAuthRequirement { Role = "Role1" });
policy.Requirements.Add(new RoleAuthRequirement { Role = "Role2" });
policy.Requirements.Add(new RoleAuthRequirement { Role = "Role3" });
});
});
services.AddIdentity<IdentityUser, IdentityRole>(); //throws out of scope ERROR!! same as AddIdentityCore
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => {
options.LoginPath = new PathString("/login");
options.AccessDeniedPath = new PathString("/denied");
});
});
When logging in I am grabbing the users role from the database and adding it as a Claim
//Login Action
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userObj.UserId.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Name, userObj.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, userObj.Role));
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
After this in my Authorization handler I cant see any claims the user is null I also cant use User.IsInRole() to verify since the user context is essentially empty.
public class RoleHandler : AuthorizationHandler<RoleAuthRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleAuthRequirement requirement)
{
var requiredRole = requirement.Role;
var hasRole = context.User.IsInRole(requiredRole);
if (hasRole)
{
context.Succeed(requirement);
}
else
{
context.Fail(new AuthorizationFailureReason(this, $"User Role {requirement.Role} missing"));
}
return Task.CompletedTask;
}
}
CodePudding user response:
You didn't regist the dbcontext which is required in Identity,Try Regist Identity as below :
services.AddDbContext<SomeContext>(options =>
options.UseSqlServer(connectionString));
services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<SomeContext>();
And After checking your codes,it seems that you are trying Login Attemps with CookieAuthentication(Not Identity) ,Is Identity Really necessary on your side?