C# 是主张比角色更好的方式吗
我正在建立一个网站(前端reactjs,后端asp.net web api core 2),并试图找出如何进行身份验证/授权 对于身份验证,我几乎会使用JWTBearer令牌,如果用户名和密码与我在数据库中为用户获得的匹配,则给他们一个令牌 我不确定的是授权,上一次我不得不做一些事情时,更多的是在数据库中设置角色,然后在用户尝试访问某些内容时检查该用户是否具有该角色 现在我在看,作者在谈论 您可以将有关用户的信息存储为声明,而不是尝试存储用户可能拥有的所有“角色”(例如管理员、用户、超级用户) 我对此感到困惑,这是如何工作的。假设我需要一个用户能够看到我的网站的非常秘密的区域(即管理区域),但另一个用户谁也登录不能看到它,因为他是一个普通用户 什么信息被用来提出这一主张?数据库中存储了什么 对于角色,您可以拥有类似用户可以拥有角色(即管理员)的功能,然后在他们尝试执行某项操作时检查该功能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令牌,如果用户名和密码与我在数据库中为用户获得的匹配,则给他们一个令牌 我不确定的是授权,上一次我不得不做一些事情时,更多的是在数据库中设置角色,然后在用户尝试访问某些内容时检查该用户是否具有该角色 现在我在看,作者在谈论 您可以将有关用户的信息存储为声明,而不是尝试存储用户可能拥有的所有“角色”(例如管理员、用户、超级用户)
我还想知道前端如何知道要隐藏什么(即显示“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 声明可用于管理比角色更广泛的用例,尤其是与角色配对时。我想到两个例子:
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
}