为什么我不能在API控制器中使用角色授权 [英] Why can't I use role authorization in my API controller

查看:70
本文介绍了为什么我不能在API控制器中使用角色授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在asp.net核心中使用单个用户帐户创建了带有react模板的react项目.我环顾了一下,发现我需要在启动文件中添加角色并添加配置文件服务,该服务似乎已经完成了一半.

I created a react project with the react template in asp.net core with individual user accounts. I have looked around and found out I needed to add roles in the startup file and add a profile service, which seems to have half worked.

我可以在授权令牌中看到这样的角色:

I can see the roles in my authorization token like this:

"role": [
    "admin",
    "bookkeeping" ], 

但是,当我将 [Authorize(Roles ="admin")] 标记添加到我的控制器时,现在即使我看到令牌包含"admin"角色,请求也被禁止.

But when I add the [Authorize(Roles = "admin")] tag to my controller the requests are now forbidden, even when i can see my token includes the role "admin".

我在这里想念什么或做错什么了?

What am I missing or doing wrong here?

这是个人资料服务:

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.Add(new Claim(JwtClaimTypes.Name, user.UserName));
        context.IssuedClaims.AddRange(roleClaims);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        return Task.CompletedTask;
    }
}

这是我的启动文件:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        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(options =>
        {
            options.AddPolicy("RequireAdministratorRole",
                 policy => policy.RequireRole("admin"));
        });

        services.AddTransient<IProfileService, ProfileService>();
        services.AddControllersWithViews()
            .AddNewtonsoftJson(options =>
                options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );
        services.AddRazorPages();

        // In production, the React files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/build";
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSpaStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseIdentityServer();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";
            if (env.IsDevelopment())
            {
                spa.UseReactDevelopmentServer(npmScript: "start");
            }
        });
    }
}

我的API控制器的小版本:

A small version of my API controller:

[Authorize(Roles = "admin")]
[Route("api/[controller]")]
public class SampleDataController : ControllerBase
{
    private readonly ApplicationDbContext _db;

    public SampleDataController(ApplicationDbContext db)
    {
        _db = db;
    }   
    [HttpGet("[action]")]
    public IEnumerable<Order> GetOrderList()
    {

        return _db.Order.ToList();
    }

}

还有我的提取方法

async populateOrderList() {
    const token = await authService.getAccessToken();
    const response = await fetch('api/SampleData/GetOrderList', {
        headers: !token ? {} : { 'Authorization': `Bearer ${token}` }
    });
    const data = await response.json();
    this.setState({ orderList: data });
}

正如您在启动文件中看到的那样,我还尝试使用带有标签 [Authorize(Policy ="RequireAdministratorRole")] 的策略.当我只使用 [Authorize]

As you can see in my startup file I have also tried using a policy, with the tag [Authorize(Policy = "RequireAdministratorRole")] instead. Also it works fine when i just use [Authorize]

我的api控制器与身份服务器位于同一项目中.

My api controllers are in the same projekt as my identity server.

非常感谢您的帮助.

推荐答案

更改启动时角色的默认声明类型,如下所示:

change your default claimtype for role in startup like this:

        services.Configure<IdentityOptions>(options =>
        {
            options.ClaimsIdentity.RoleClaimType = JwtClaimTypes.Role;
        });

这篇关于为什么我不能在API控制器中使用角色授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆