Asp.Net Core WebApi:授权属性错误 403 [英] Asp.Net Core WebApi: Authorize attribute Error 403
问题描述
我在 Asp.Net Core WebApi 项目中工作并创建了一个角色 admin" 并将其添加到我的用户.但是如果我以管理员身份登录,第一个方法将返回This is admin!",而第二个方法返回错误 403 Forbidden.
I work in Asp.Net Core WebApi project and created a role "admin" and add it to my user. But if I logged in as an admin, the first method will return "This is admin!", but the second method returns an error 403 Forbidden.
如果我从 Authorize 属性中删除 Roles 参数,一切都会好起来的.我不明白为什么我无法访问第二种方法,因为我的用户具有管理员角色.
If I remove the Roles parameter from the Authorize attribute, everything will go fine. I do not understand why I can not access the second method because my user has an admin role.
// Host/api/roles/getroles
[Authorize]
[HttpGet]
public async Task<IEnumerable<string>> GetRoles()
{
var user = await _userManager.GetUserAsync(User);
bool isAdmin = await _userManager.IsInRoleAsync(user, Roles.AdminRole);
if (isAdmin)
return new[] {"This is admin!"};
return await _userManager.GetRolesAsync(user);
}
// ===== Admin Methods =====
// Host/api/roles/createrole
[Authorize(Roles = Roles.AdminRole)]
[HttpPost]
public async Task<IActionResult> CreateRole([FromBody] CreateRoleViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
var result = await _roleManager.CreateAsync(new IdentityRole(model.RoleName));
if (!result.Succeeded)
return BadRequest(result);
return Ok();
}
在我发送的第二种方法的请求中:
In the request for the second method I send:
标题:内容类型:应用程序/json授权:承载 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJh...
身体:RoleName = "程序员"
也许我需要在标题中添加一些内容?
Maybe I need to add something to the Headers?
Startup.cs
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// ===== Add DbContext ========
var connectionString = Configuration.GetConnectionString("DbConnection");
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
// ===== Add Identity ========
services.AddIdentity<User, IdentityRole> (opts=> {
opts.Password.RequiredLength = 5;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequireLowercase = false;
opts.Password.RequireUppercase = false;
opts.Password.RequireDigit = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// ===== Add Jwt Authentication ========
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // => remove default claims
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero // remove delay of token when expire
};
});
// ===== Add MVC =====
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ApplicationDbContext dbContext
)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// ===== Use Authentication ======
app.UseAuthentication();
// ===== Use MVC =====
app.UseMvc();
}
}
创建 JWT 令牌方法
// ===== Token =====
private async Task<object> GenerateJwtToken(IdentityUser user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"]));
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
推荐答案
我更改了我的 GenerateJwtToken() 方法以添加角色作为声明:
I changed my GenerateJwtToken() method to add roles as a claims:
// Get User roles and add them to claims
var roles = await _userManager.GetRolesAsync(user);
AddRolesToClaims(claims, roles);
// ===== Token =====
private async Task<object> GenerateJwtToken(User user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id),
};
// Get User roles and add them to claims
var roles = await _userManager.GetRolesAsync(user);
AddRolesToClaims(claims, roles);
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"]));
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
private void AddRolesToClaims(List<Claim> claims, IEnumerable<string> roles)
{
foreach (var role in roles)
{
var roleClaim = new Claim(ClaimTypes.Role, role);
claims.Add(roleClaim);
}
}
这篇关于Asp.Net Core WebApi:授权属性错误 403的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!