简体   繁体   English

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

[英]Role Authorization Not Working with React/ASP.NET Core API

I created a react project with the default react template in asp.net core with individual user accounts.我使用 asp.net 核心中的默认反应模板创建了一个反应项目,其中包含个人用户帐户。 [Authorize] attribute works fine however when I try to implement [Authorize(Roles = "Administrator")] I get a 403 status code. [Authorize] 属性工作正常,但是当我尝试实现 [Authorize(Roles = "Administrator")] 时,我得到一个 403 状态码。

I've added ProfileService to add claims.我添加了 ProfileService 来添加声明。

ProfileService.cs配置文件服务.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;
    }
}

"role": "Administrator" exists in my JWT token. “角色”:“管理员”存在于我的 JWT 令牌中。

I have the Authorize attribute added to my controller.我在 controller 中添加了 Authorize 属性。

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

I have also configured my Startup.cs as below.我还配置了我的 Startup.cs,如下所示。

Startup.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";
        });
    }

Unsure where I'm going wrong with this.不确定我在哪里出错了。

If you want to use the built-in Role authorization, you will have to change the way you assign the role claim from this:如果要使用内置角色授权,则必须更改分配角色声明的方式:

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

to this:对此:

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

the better way will be to use policy-based authorization https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0 .更好的方法是使用基于策略的授权https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0

  1. Configure your policy in ConfigureServices :ConfigureServices中配置您的策略:

     services.AddAuthorization(options => { options.AddPolicy("RequireAdministratorRole", policy => policy.RequireClaim(ClaimTypes.Role, "Administrator")); });
  2. In ProfileService在 ProfileService 中

     var claims = roles.Select(role => new Claim(ClaimTypes.Role, role)).ToList();
  3. Add to the controller:添加到 controller:

    [Authorize(Policy = "RequireAdministratorRole")] [授权(策略=“RequireAdministratorRole”)]

It might not work because of the Microsoft claim name inconsistency can be fixed with:它可能不起作用,因为 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>();
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 基于角色的授权属性在 ASP.NET Core MVC 中不起作用 - Role based authorization attribute not working in ASP.NET Core MVC ASP.NET Core 3.0 基于角色的授权不起作用 - ASP.NET Core 3.0 Role Based Authorization not working 基于 ASP.NET Core 3.1 Web API 角色的授权不起作用 - ASP.NET Core 3.1 Web API Role based authorization not working 通过使用JWT令牌在Web API上声明角色授权-Asp.net核心标识 - Authorization by a Claim of a Role on Web API using JWT Token- Asp.net Core Identity IdentityServer4 基于角色的 Web API 授权与 ASP.NET Core 标识 - IdentityServer4 Role Based Authorization for Web API with ASP.NET Core Identity ASP.NET 核心 WebApi Jwt 基于角色的授权不起作用 - ASP.NET Core WebApi Jwt Role-based Authorization not working Asp.NET Core MVC基于角色的授权 - Asp.NET Core MVC Role based Authorization Windows身份验证Asp.net核心2数据库角色授权 - Windows Authentication Asp.net core 2 database role authorization ASP.NET Core 3.1 中基于角色的授权,带有身份和外部登录 - Role based authorization in ASP.NET Core 3.1 with Identity and ExternalLogin 具有基于角色的授权的ASP.NET Web Api - ASP.NET Web Api with Role based authorization
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM