Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.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# 是主张比角色更好的方式吗_C#_Authorization_Asp.net Core 2.0_Roles_Claims - Fatal编程技术网

C# 是主张比角色更好的方式吗

C# 是主张比角色更好的方式吗,c#,authorization,asp.net-core-2.0,roles,claims,C#,Authorization,Asp.net Core 2.0,Roles,Claims,我正在建立一个网站(前端reactjs,后端asp.net web api core 2),并试图找出如何进行身份验证/授权 对于身份验证,我几乎会使用JWTBearer令牌,如果用户名和密码与我在数据库中为用户获得的匹配,则给他们一个令牌 我不确定的是授权,上一次我不得不做一些事情时,更多的是在数据库中设置角色,然后在用户尝试访问某些内容时检查该用户是否具有该角色 现在我在看,作者在谈论 您可以将有关用户的信息存储为声明,而不是尝试存储用户可能拥有的所有“角色”(例如管理员、用户、超级用户)

我正在建立一个网站(前端reactjs,后端asp.net web api core 2),并试图找出如何进行身份验证/授权

对于身份验证,我几乎会使用JWTBearer令牌,如果用户名和密码与我在数据库中为用户获得的匹配,则给他们一个令牌

我不确定的是授权,上一次我不得不做一些事情时,更多的是在数据库中设置角色,然后在用户尝试访问某些内容时检查该用户是否具有该角色

现在我在看,作者在谈论

您可以将有关用户的信息存储为声明,而不是尝试存储用户可能拥有的所有“角色”(例如管理员、用户、超级用户)

我对此感到困惑,这是如何工作的。假设我需要一个用户能够看到我的网站的非常秘密的区域(即管理区域),但另一个用户谁也登录不能看到它,因为他是一个普通用户

什么信息被用来提出这一主张?数据库中存储了什么

对于角色,您可以拥有类似用户可以拥有角色(即管理员)的功能,然后在他们尝试执行某项操作时检查该功能


我还想知道前端如何知道要隐藏什么(即显示“admin area”的链接),因为您是否可以返回一个结果,表明他们有一个允许他们查看admin area的声明?

角色仍然可以像在旧版本中一样使用。声明只是一种存储更多用户数据并提供更多认证灵活性的方法。您可以将它们添加到如下列表中:

List<Claim> claims = new List<Claim> {
    new Claim(ClaimTypes.Name, "username"),
    new Claim(ClaimTypes.Role, "First Role"),
    new Claim(ClaimTypes.Role, "Second Role"),
    new Claim(ClaimTypes.Role, "Third Role")
};
List claims=新列表{
新索赔(ClaimTypes.Name,“用户名”),
新索赔(ClaimTypes.Role,“第一角色”),
新索赔(ClaimTypes.Role,“第二角色”),
新索赔(ClaimTypes.Role,“第三方角色”)
};
您可以使用
[authorize(Roles=“user,superUser”)]
授权任何控制器或操作。如果要根据角色向用户显示某些内容,可以使用
@If(user.IsInRole(“user”))

在创建JWT时,您可以查看这个类:


它具有实用功能,可以创建具有给定用户名的JWT,以及接收用户名和逗号分隔的角色字符串的JWT

声明可用于管理比角色更广泛的用例,尤其是与角色配对时。我想到两个例子:

  • 要求用户具有特定的信誉才能编辑记录
  • 要求用户至少21岁才能订购特定产品
  • 可以创建一个“超过21岁”的角色和一个“超过1000名”的角色,但保持角色成员身份变得很难;您需要设置作业,以便在用户的年龄或声誉发生变化时从这些角色中添加(或删除)用户

    相反,让您的JWT包含声誉和出生日期声明:

    identity.AddClaim(new Claim("Reputation", 722));
    identity.AddClaim(new Claim("BirthDate", new DateTime(2000, 1, 1)));
    
    然后,您的代码可以实现一个
    要求
    授权处理程序
    ,该处理程序根据这些索赔值计算用户是否应获得授权:

    public class ReputationRequirement : IAuthorizationRequirement
    {
        public int Reputation { get; private set; }
    
        public ReputationRequirement (int reputation)
        {
            Reputation = reputation;
        }
    }
    
    AuthorizationHandler
    按照以下方式配对:

    public class ReputationHandler : AuthorizationHandler<ReputationRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ReputationRequirement requirement)
        {
            if (!context.User.HasClaim(c => c.Type == "Reputation"))
            {
                return Task.CompletedTask;
            }
    
            var reputation = context.User.FindFirst(c => c.Type == "Reputation").Value as int;
            if (reputation >= requirement.Reputation)  
                context.Succeed(requirement);
            return Task.CompletedTask;
        }
    }
    
    最后,您可以使用策略标记MVC控制器或方法:

    [Authorize(Policy = "OldAndWise")]
    public class StackOverflowWineController : Controller
    {
        // omitted for brevity
    }
    
    请注意,链接到的示例比这个简短的代码片段更详细


    关于数据库中声明的存储,这取决于用例。当将角色视为声明时,仍然会有
    UserRoles
    RoleMembership
    表。对于
    Reptuation
    BirthDate
    ,将它们存储在用户表中可能更有意义,而不是存储在某种专用的通用
    声明
    表中。

    不完全确定他这句话的意思。我还没有深入研究旧的授权方法。但角色实际上是一种主张。您仍然可以使用任何东西,例如
    [Authorize(Roles=“user,superUser”)]
    。您还可以执行
    User.IsInRole(“用户”)
    在更新的数据库中存储角色会是什么样子?和以前一样,用户有一个角色(或者可以是多对多)。我想还是一样吧?这样您就不必检查每个请求并查看它们是否是该角色的一部分,因为它安全地存储在声明中,然后合并到JWT令牌中?您可以创建一个具有标识的.net核心网站,以查看该结构的具体工作方式。您可以使用
    dotnet new mvc-o mySite-au Individual
    来设置一个具有标识的新web应用程序。然后,您可以检查db结构和控制器角色主要存储在claims principal中,而claims principal又保存在cookie或JWT等中。这样做是为了避免每次都检查db(这将是一个繁重的过程)。您可以随时为更高级的角色检查创建策略。我将查看mvc项目,但我正在制作一个API,在“个人”下唯一的选项是azure的东西,没有选项让您自己的db将这些数据存储在其中。声明和身份验证的概念是身份验证方案的一部分,它将独立于JWT或Cookie。您可以查看identity的db i是如何构造的,以及它是如何用于登录和存储声明的。然后,您可以使用相同的想法并将声明保存到JWT中。
    [Authorize(Policy = "OldAndWise")]
    public class StackOverflowWineController : Controller
    {
        // omitted for brevity
    }