Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在ASP.net核心标识中实现基于权限的授权?_C#_Asp.net Web Api_Asp.net Core_Asp.net Identity - Fatal编程技术网

C# 如何在ASP.net核心标识中实现基于权限的授权?

C# 如何在ASP.net核心标识中实现基于权限的授权?,c#,asp.net-web-api,asp.net-core,asp.net-identity,C#,Asp.net Web Api,Asp.net Core,Asp.net Identity,我正在尝试使用asp.net Identity Core保护我的webAPI。现在我想动态创建角色,并在我的管理面板中设置和删除对它们的权限 例如,我有以下权限列表: 注册任务 分配任务 更改任务状态 验证任务状态 现在,我想创建不同的角色,并根据需要为它们设置此权限,然后将这些角色分配给每个用户 我在Identity framework的UserManager和RoleManager中进行了搜索,但无法创建此功能 是否有实现此功能的方法? 我发现这很有用,但这是关于dotnet的我发现一种

我正在尝试使用asp.net Identity Core保护我的webAPI。现在我想动态创建角色,并在我的管理面板中设置和删除对它们的权限

例如,我有以下权限列表:

  • 注册任务
  • 分配任务
  • 更改任务状态
  • 验证任务状态
现在,我想创建不同的角色,并根据需要为它们设置此权限,然后将这些角色分配给每个用户

我在Identity framework的UserManager和RoleManager中进行了搜索,但无法创建此功能

是否有实现此功能的方法?
我发现这很有用,但这是关于dotnet的

我发现一种方法,它使用声明和策略在链接中创建基于权限的授权

我创建一个自定义声明类型,例如Application.Permission,然后创建一些类,如下所示来定义我的权限:

public class CustomClaimTypes
{
    public const string Permission = "Application.Permission";
}

public static class UserPermissions
{
    public const string Add = "users.add";
    public const string Edit = "users.edit";
    public const string EditRole = "users.edit.role";
} 
public static class PrincipalPermission{

       public static List<Func<AuthorizationHandlerContext, bool>> Criteria = new List<Func<AuthorizationHandlerContext, bool>>
        {
            CanCreateUser
        };

        public static bool CanCreateUser(this AuthorizationHandlerContext ctx)
        {
            return ctx.User.IsInRole(RoleEnum.Admin.ToString());
        }
}
然后我创建我的角色,然后将这些权限作为声明分配给具有keyApplicationPermission的角色

await roleManager.CreateAsync(new ApplicationRole("User"));
var userRole = await roleManager.FindByNameAsync("User");
await roleManager.AddClaimAsync(userRole, new Claim(CustomClaimTypes.Permission, Permissions.User.View));    
await roleManager.AddClaimAsync(userRole, new Claim(CustomClaimTypes.Permission, Permissions.Team.View));
在下一步中,当用户尝试登录到系统时,我将这些声明添加到我的令牌中:

var roles = await _userManager.GetRolesAsync(user);
var userRoles = roles.Select(r => new Claim(ClaimTypes.Role, r)).ToArray();
var userClaims = await _userManager.GetClaimsAsync(user).ConfigureAwait(false);
var roleClaims = await GetRoleClaimsAsync(roles).ConfigureAwait(false);
var claims = new[]
             {
                 new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                 new Claim(ClaimTypes.Email, user.Email),
                 new Claim(ClaimTypes.Name, user.UserName)
             }.Union(userClaims).Union(roleClaims).Union(userRoles);

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SigningKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
    issuer: _jwtSettings.Issuer,
    audience: _jwtSettings.Audience,
    claims: claims,
    expires: DateTime.UtcNow.AddYears(1),
    signingCredentials: creds);
然后,我通过以下方式创建我的策略:

public static class PolicyTypes
{
    public static class Users
    {
        public const string Manage = "users.manage.policy";
        public const string EditRole = "users.edit.role.policy";
    }
}
然后,我在ConfigureServiceSection中的startup.cs文件中设置授权服务:

services.AddAuthorization(options =>
{
    options.AddPolicy(PolicyTypes.Users.Manage, policy => { policy.RequireClaim(CustomClaimTypes.Permission, Permissions.Users.Add); });
    options.AddPolicy(PolicyTypes.Users.EditRole, policy => { policy.RequireClaim(CustomClaimTypes.Permission, Permissions.Users.EditRole); });
}
最后,我在路线上设置策略并完成:

[Authorize(Policy = PolicyTypes.Users.Manage)]
public async Task<IEnumerable<TeamDto>> GetSubTeams(int parentId)
{
    var teams = await _teamService.GetSubTeamsAsync(parentId);
    return teams;
}
[授权(策略=策略类型.用户.管理)]
公共异步任务GetSubTeams(int parentId)
{
var teams=wait_teamService.GetSubTeamsAsync(parentId);
返回队;
}

另一种解决方案是使用funcs来填充策略,请参见以下示例:


记住这一点,你可以做如下的事情

首先,为您的所有个人权限创建一个类:

public class CustomClaimTypes
{
    public const string Permission = "Application.Permission";
}

public static class UserPermissions
{
    public const string Add = "users.add";
    public const string Edit = "users.edit";
    public const string EditRole = "users.edit.role";
} 
public static class PrincipalPermission{

       public static List<Func<AuthorizationHandlerContext, bool>> Criteria = new List<Func<AuthorizationHandlerContext, bool>>
        {
            CanCreateUser
        };

        public static bool CanCreateUser(this AuthorizationHandlerContext ctx)
        {
            return ctx.User.IsInRole(RoleEnum.Admin.ToString());
        }
}
现在可以将其添加到控制器中:

    [Authorize(Policy = nameof(PrincipalPermissions.CanCreateUser))]
    public async Task<UserDto> Create([FromBody] CreateUserCommand cmd)
    {
       return await HandleCreateUser(cmd);
    }
[Authorize(Policy=nameof(PrincipalPermissions.CanCreateUser))]
公共异步任务创建([FromBody]CreateUserCommand cmd)
{
返回等待HandleCreateUser(cmd);
}

顺便说一句,如果有人认为将这些方法添加到
标准列表中很烦人,我很乐意为您效劳,如果有人能想出更好的解决方案,我将不胜感激:)

不可能重复,但这不是。我正在搜索基于权限的授权,但在您的链接中,它是关于基于角色的授权,特别是关于创建角色。您将如何解决cookie大小限制问题?每个权限至少有50个字符,大小限制低至4K,应用程序很快就会耗尽空间。。。当然,除非它回到角色系统。我的案例是一个WebAPI,我没有使用cookies。此外,我们的权限由JWT令牌在服务器和客户端之间传递,它可以保存前端首选的任何位置。对不起,这是指HTTP头大小,而不是cookie。我想你从来都不需要超过一打或两个权限,谢谢你对实现的澄清。我基于此使用JWT(授权头),所以不容易通过限制。但是我们每个用户最多有40个权限,这是可以的。是的!当然我们为所有用户创建一个内存中的黑名单,因为他们的角色发生了变化。并且还将JWT令牌生存期缩短,并实现刷新令牌机制。