gpt4 book ai didi

c# - ASP.NET Core JWT 将角色声明映射到 ClaimsIdentity

转载 作者:IT王子 更新时间:2023-10-29 04:29:06 26 4
gpt4 key购买 nike

我想使用 JWT 保护 ASP.NET Core Web API。此外,我希望可以选择直接在 Controller 操作属性中使用 token 负载中的角色。

现在,虽然我确实找到了如何将其与策略一起使用:

Authorize(Policy="CheckIfUserIsOfRoleX")
ControllerAction()...

我更希望可以选择使用一些常用的东西,比如:

Authorize(Role="RoleX")

其中角色将从 JWT 负载自动映射。

{
name: "somename",
roles: ["RoleX", "RoleY", "RoleZ"]
}

那么,在 ASP.NET Core 中实现这一点的最简单方法是什么?有没有办法通过一些设置/映射使它自动工作(如果是这样,在哪里设置它?)或者我应该在验证 token 后拦截 ClaimsIdentity 的生成并手动添加角色声明(如果是这样,在哪里/如何做?)?

最佳答案

生成 JWT 时需要获取有效声明。这是示例代码:

登录逻辑:

[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login([FromBody] ApplicationUser applicationUser) {
var result = await _signInManager.PasswordSignInAsync(applicationUser.UserName, applicationUser.Password, true, false);
if(result.Succeeded) {
var user = await _userManager.FindByNameAsync(applicationUser.UserName);

// Get valid claims and pass them into JWT
var claims = await GetValidClaims(user);

// Create the JWT security token and encode it.
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims: claims,
notBefore: _jwtOptions.NotBefore,
expires: _jwtOptions.Expiration,
signingCredentials: _jwtOptions.SigningCredentials);
//...
} else {
throw new ApiException('Wrong username or password', 403);
}
}

获取基于 UserRolesRoleClaimsUserClaims 表的用户声明(ASP.NET Identity):

private async Task<List<Claim>> GetValidClaims(ApplicationUser user)
{
IdentityOptions _options = new IdentityOptions();
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
new Claim(_options.ClaimsIdentity.UserIdClaimType, user.Id.ToString()),
new Claim(_options.ClaimsIdentity.UserNameClaimType, user.UserName)
};
var userClaims = await _userManager.GetClaimsAsync(user);
var userRoles = await _userManager.GetRolesAsync(user);
claims.AddRange(userClaims);
foreach (var userRole in userRoles)
{
claims.Add(new Claim(ClaimTypes.Role, userRole));
var role = await _roleManager.FindByNameAsync(userRole);
if(role != null)
{
var roleClaims = await _roleManager.GetClaimsAsync(role);
foreach(Claim roleClaim in roleClaims)
{
claims.Add(roleClaim);
}
}
}
return claims;
}

Startup.cs中请将需要的策略添加到授权中:

void ConfigureServices(IServiceCollection service) {
services.AddAuthorization(options =>
{
// Here I stored necessary permissions/roles in a constant
foreach (var prop in typeof(ClaimPermission).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy))
{
options.AddPolicy(prop.GetValue(null).ToString(), policy => policy.RequireClaim(ClaimType.Permission, prop.GetValue(null).ToString()));
}
});
}

ClaimPermission:

public static class ClaimPermission
{
public const string
CanAddNewService = "Tự thêm dịch vụ",
CanCancelCustomerServices = "Hủy dịch vụ khách gọi",
CanPrintReceiptAgain = "In lại hóa đơn",
CanImportGoods = "Quản lý tồn kho",
CanManageComputers = "Quản lý máy tính",
CanManageCoffees = "Quản lý bàn cà phê",
CanManageBillards = "Quản lý bàn billard";
}

使用类似的代码片段获取所有预定义的权限并将其插入到 asp.net 权限声明表中:

var staffRole = await roleManager.CreateRoleIfNotExists(UserType.Staff);

foreach (var prop in typeof(ClaimPermission).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy))
{
await roleManager.AddClaimIfNotExists(staffRole, prop.GetValue(null).ToString());
}

我是 ASP.NET 的初学者,如果您有更好的解决方案,请告诉我。

而且,当我将所有声明/权限放入 JWT 时,我不知道有多糟糕。太长?表现 ?我是否应该将生成的 JWT 存储在数据库中并稍后检查它以获得有效的用户角色/声明?

关于c# - ASP.NET Core JWT 将角色声明映射到 ClaimsIdentity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42036810/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com