ASP.NET Core 8 身份授权-使用角色策略进行身份验证

问题描述 投票:0回答:1

在 ASP.NET Core 8 Web API 中,我有与授权和身份验证相关的配置:

builder.Services.AddAuthentication("Bearer").AddJwtBearer();
builder.Services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

此版本允许我使用 cookie 或不记名令牌进行连接,但我无法使用需要角色授权的策略,因为它不会初始化角色管理器服务。

这个版本:

builder.Services.AddAuthentication("Bearer").AddJwtBearer();
builder.Services
        .AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddTransient<IEmailSender<IdentityUser>, MyEmailSender<IdentityUser>>();

允许我仅使用 cookie 与我的应用程序交互。如果尝试使用不记名令牌会引发此错误:

System.InvalidOperationException:没有为方案“Identity.Bearer”注册登录身份验证处理程序。注册的登录方案有:Identity.Application、Identity.External、Identity.TwoFactorRememberMe、Identity.TwoFactorUserId。您是否忘记调用 AddAuthentication().AddCookie("Identity.Bearer",...)?

在 Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext 上下文、字符串方案、ClaimsPrincipal 主体、AuthenticationProperties 属性)
在 Microsoft.AspNetCore.Identity.SignInManager

1.SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable
1 个附加声明)
在 Microsoft.AspNetCore.Identity.SignInManager
1.SignInOrTwoFactorAsync(TUser user, Boolean isPersistent, String loginProvider, Boolean bypassTwoFactor)   at Microsoft.AspNetCore.Identity.SignInManager
1.PasswordSignInAsync(TUser 用户,字符串密码,布尔值 isPersistent,布尔值 lockoutOnFailure)
在 Microsoft.AspNetCore.Identity.SignInManager
1.PasswordSignInAsync(String userName, String password, Boolean isPersistent, Boolean lockoutOnFailure)   at Microsoft.AspNetCore.Routing.IdentityApiEndpointRouteBuilderExtensions.<>c__1
1.d.MoveNext()

我需要的是一个允许我处理角色管理器并可以使用 cookie 和不记名令牌进行身份验证的版本。我只需要 ASP.NET Core 令牌,不需要第三方授权令牌。

注意:这是我的身份验证配置,使用文档对其进行调整,但这样我可以使用令牌登录,但无法访问角色管理器的服务!!!

    #region Config authorization   
    // Add services to the container.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    builder.Services.AddDbContext<ApplicationDbContext>(
            (options) => options
                    .UseSqlServer(builder.Configuration.GetConnectionString("Communities")));
    builder.Services.AddAuthorization();
    builder.Services.AddIdentityApiEndpoints<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
    builder.Services.AddTransient<IEmailSender<IdentityUser>, CommunitiesEmailSender<IdentityUser>>();
    builder.Services.AddAuthorizationBuilder()
        .AddPolicy(Policy.Admin, policy => policy
            .RequireAuthenticatedUser()
            .RequireRole(Roles.Admin));
    #endregion


    var app = builder.Build();

    #region enhance auth
    app.MapIdentityApi<IdentityUser>();
    app.UseAuthentication();
    app.UseAuthorization();
    #endregion

但是有了这个配置和这个动作

    [HttpPost]
    [Authorize(Policy = Policy.Admin)]
    [Route(nameof(SetUserRole))]
    public async Task SetUserRole(string userName, string desiredRole)
    {
        await CheckRoles();
        await AddRole(userName, desiredRole);
    }

总是收到403 Forbidden,策略设置没问题,只需使用常量以避免拼写错误。 另外,我至少需要在一个控制器中访问角色管理器

asp.net-core-webapi asp.net-core-identity asp.net-core-8
1个回答
0
投票

阅读官方文档,似乎不允许使用角色来保护SPA。

"Using roles to add claims to a user can confuse the boundary 
between the user and their individual claims. This confusion is 
why the SPA templates are not designed around roles. In 
addition, for organizations migrating from an on-premises 
legacy system the proliferation of roles over the years can 
mean a role claim may be too large to be contained within a 
token usable by SPAs." 

由于我正在使用 SPA 类型的应用程序,因此将使用简单的声明方法。

© www.soinside.com 2019 - 2024. All rights reserved.