角色授权不适用于 React/ASP.NET Core API



我在核心中使用默认的 react 模板创建了一个 react 项目 asp.net 具有个人用户帐户。[授权] 属性工作正常,但是当我尝试实现 [授权(角色 = "管理员"(] 时,我收到 403 状态代码。

我添加了配置文件服务来添加声明。

配置文件服务.cs

public class ProfileService : IProfileService
{
protected UserManager<ApplicationUser> mUserManager;
public ProfileService(UserManager<ApplicationUser> userManager)
{
mUserManager = userManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
ApplicationUser user = await mUserManager.GetUserAsync(context.Subject);
IList<string> roles = await mUserManager.GetRolesAsync(user);
IList<Claim> roleClaims = new List<Claim>();
foreach (string role in roles)
{
roleClaims.Add(new Claim(JwtClaimTypes.Role, role));
}
context.IssuedClaims.AddRange(roleClaims);
}
public Task IsActiveAsync(IsActiveContext context)
{
return Task.CompletedTask;
}
}

"角色":"管理员"存在于我的 JWT 令牌中。

我已将授权属性添加到我的控制器。

[Authorize(Roles = "Administrator")]
[HttpGet]
public async Task<ActionResult<IEnumerable<Order>>> GetOrders()
{
return await _context.Orders.ToListAsync();
}

我还配置了我的启动.cs如下所示。

启动.cs

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
//services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
//    .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddAuthorization();
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.RoleClaimType = JwtClaimTypes.Role;
});
services.AddTransient<IProfileService, ProfileService>();
services.AddControllersWithViews();
services.AddRazorPages();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}

不知道我哪里出了问题。

如果要使用内置的角色授权,则必须从下面更改分配角色声明的方式:

roleClaims.Add(new Claim(JwtClaimTypes.Role, role));

对此:

roleClaims.Add(new Claim(ClaimTypes.Role, role));

更好的方法是使用基于策略的授权 https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0。

  1. 在配置服务中配置策略:

    services.AddAuthorization(options =>
    {
    options.AddPolicy("RequireAdministratorRole",
    policy => policy.RequireClaim(ClaimTypes.Role, "Administrator"));
    });
    
  2. 在配置文件服务中

    var claims = roles.Select(role => new Claim(ClaimTypes.Role, role)).ToList();
    
  3. 添加到控制器:

    [授权(策略 = "要求管理员角色"(]

它可能不起作用,因为Microsoft声明名称不一致可以通过以下方式修复:

services.Configure<JwtBearerOptions>(options =>
{
var validator = options.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().SingleOrDefault();
// Turn off Microsoft's JWT handler that maps claim types to .NET's long claim type names
validator.InboundClaimTypeMap = new Dictionary<string, string>();
validator.OutboundClaimTypeMap = new Dictionary<string, string>();
});

最新更新