我使用个人用户帐户在asp.net核心中使用默认的react模板创建了一个react项目。 [Authorize]属性工作正常,但是当我尝试实现[Authorize(Roles =“ Administrator”)]时,我得到了403状态代码。
我添加了ProfileService来添加声明。
ProfileService.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属性添加到控制器中。
[Authorize(Roles = "Administrator")]
[HttpGet]
public async Task<ActionResult<IEnumerable<Order>>> GetOrders()
{
return await _context.Orders.ToListAsync();
}
我还如下配置了Startup.cs。
Startup.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";
});
}
不确定我要怎么做。
答案 0 :(得分:0)
如果要使用内置的角色授权,则必须更改为此分配角色声明的方式:
roleClaims.Add(new Claim(JwtClaimTypes.Role, role));
对此:
roleClaims.Add(new Claim(ClaimTypes.Role, role));
答案 1 :(得分:0)
更好的方法是使用基于策略的授权 https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0。
在 ConfigureServices 中配置您的政策:
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdministratorRole",
policy => policy.RequireClaim(ClaimTypes.Role, "Administrator"));
});
在 ProfileService 中
var claims = roles.Select(role => new Claim(ClaimTypes.Role, role)).ToList();
添加到控制器:
[授权(Policy = "RequireAdministratorRole")]
它可能不起作用,因为 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>();
});