ASP.NET 标识和声明
Posted
技术标签:
【中文标题】ASP.NET 标识和声明【英文标题】:ASP.NET Identity and Claims 【发布时间】:2014-03-12 19:03:21 【问题描述】:我正在尝试摆脱 WebForms 并学习 MVC,特别是使用新的 ASP.NET Identity 模型。但是,我似乎找不到任何来自 Microsoft 的正式文档来演示如何创建声明对象并将其存储在数据库中以供经过身份验证的用户使用。
我的网站,需要做以下事情:
-
验证用户 - TICK
创建一个声明,并在其中存储用户信息,以便我可以在整个会话期间使用它 - 不打勾
从新的 ASP.NET 角色表中拉回用户角色 - 不勾选
任何人都可以阐明如何实现这一目标吗?
【问题讨论】:
对 .NET Core 的声明和身份的很好解释:andrewlock.net/introduction-to-authentication-with-asp-net-core(不是我的) 【参考方案1】:老实说,我自己仍在学习 Identity。诚然,微软提供的文档可能会更好,但我从来没有发现他们的任何文档都有帮助。最好的东西总是来自社区,不幸的是,Identity 仍然很新,社区还没有时间真正充实它。
也就是说,这就是我所知道的,但我知道可能还有更好的方法,但我根本不知道。
索赔
您的UserManager
具有三种显着性方法:GetClaimsAsync
、AddClaimAsync
和RemoveClaimAsync
。
获取用户的所有声明:
var claims = await UserManager.GetClaimsAsync(userId);
您可以通过以下方式获取当前用户的 id:
var userId = User.Identity.GetUserId();
获得声明后,提取特定声明:
var someClaim = claims.FirstOrDefault(c => c.Type == "SomeClaimType");
其中“SomeClaimType”是声明添加时的名称。在某些情况下,这可能是一个完全限定的 URN,或者它可能只是一个简单的字符串。如果这不是您亲自添加的,最好的办法就是在调试会话期间检查 claims
变量,看看您实际上有什么。
此外,由于声明列表是可查询的,您几乎可以在其上执行任何您想要的 LINQ 查询,Where
、Count
等。
添加新声明:
await UserManager.AddClaimAsync(userId, new Claim("SomeClaimType", claimValue));
并删除声明:
await UserManager.RemoveClaimAsync(userId, someClaim);
角色
角色的工作方式类似。获取用户的所有角色:
var roles = await UserManager.GetRolesAsync(userId);
查看用户是否属于特定角色:
var hasRole = await UserManager.IsInRoleAsync(userId, "SomeRole");
将用户添加到特定角色:
await UserManager.AddToRoleAsync(userId, "SomeRole");
并删除:
await UserManager.RemoveFromRoleAsync(userId, "SomeRole");
首先添加角色有点不同;你必须创建一个RoleStore
的实例。
var roleStore = new RoleStore<IdentityRole>(context);
然后,您可以使用它来管理所有角色。例如,要创建一个新角色:
await roleStore.CreateAsync(new IdentityRole("RoleName"));
删除:
var identityRole = await roleStore.FindByNameAsync("RoleName");
await roleStore.DeleteAsync(identityRole);
目前无法使用特定于身份的 API 获取 所有 角色,但您始终可以退回到直接使用实体框架进行查询:
var allRoles = context.Roles.OrderBy(o => o.Name);
【讨论】:
哇,谢谢克里斯。我的假设是,一旦用户通过身份验证,您就会创建一个声明。我将其正确/错误地视为该用户的某种形式的会话/护照。所以,用户登录成功,根据他们的设置建立一个声明,我需要从数据库中获取。还是我走远了? 有点。声明是持久的,所以这不是您需要在每次登录时构建的东西。声明最好被视为存储临时信息的一种方式,这些信息可能不适用于每个用户,或者不适合实际放在用户表上。存储 Facebook 身份验证令牌将是正确使用声明的一个很好的例子。但是,在这种情况下,一旦用户使用 Facebook 登录并且您保存了声明,您就可以随时从声明中获取他们的身份验证令牌。您不必一直添加它。 我整周都在寻找可靠的文档,但我认为 AspNet.Identity 文档非常薄弱:|作为结论,我从您的回复中了解到:“我们应该自己管理索赔”await UserManager.AddClaimAsync(userId, new Claim("SomeClaimType", claimValue));
应该调用将索赔存储在数据库中,对吗?因为context.Identity.AddClaim()
方法对数据库没有影响。
为什么我没有早点找到这篇文章?你帮我找出了困扰我好几周的事情。
是的,我明白这一点,但我的情况是一些用户会有相同的声明,如 ApprovePurchaseOrder
、 ApproveSalesOrder
、 Refund
等。现在我不想硬线这些字符串所以我想我必须自己将它们存储在某个地方,并在创建用户时分配这些Claims
,然后根据这些验证用户操作。【参考方案2】:
关于 Asp.Net Identity,我强烈推荐 Brock Allen 的实现,称为“Identity Reboot”。 Identity Reboot 基本上是 ASP.NET Identity 的一组扩展。它的灵感来自于对 ASP.NET Identity 实现的挫败感。
您可以阅读介绍性文章here。您可以从 githubhere 下载源代码和示例。
您可以使用 nuget 安装它:
www.nuget.org/packages/BrockAllen.IdentityReboot/
www.nuget.org/packages/BrockAllen.IdentityReboot.Ef/ (for entity framework)
【讨论】:
以上是关于ASP.NET 标识和声明的主要内容,如果未能解决你的问题,请参考以下文章
更改 ASP.NET SPA 模板中的 ASP.NET 标识代码的原因?