如何为 Asp.NET MVC 5 创建 ClaimsIdentity 对象?
Posted
技术标签:
【中文标题】如何为 Asp.NET MVC 5 创建 ClaimsIdentity 对象?【英文标题】:How do I create a ClaimsIdentity object for Asp.NET MVC 5? 【发布时间】:2013-12-05 04:43:03 【问题描述】:我正在使用 .NET MVC 5 应用程序。我不想使用实体框架。我想对 RavenDB 数据库进行身份验证。在我看来,我想替换帐户控制器附带的UserManager
。我想我可以重写所有 UserManager 函数来使用我的数据库,除了我不理解 ClaimsIdentity
对象。
在SignInAsync
方法中,有一个对UserManager.CreateIdentityAsync(...)
的调用。我知道它返回一个ClaimsIdentity
对象。我不知道如何自己创建一个 ClaimsIdentity 对象。
我看到它有 4 个属性 Actor
、BootstrapContext
、Claims
和 Label
。我不知道这些属性是做什么用的,也不知道如何正确生成它们。我认为正确生成它们很重要,因为它是身份验证 cookie 的制作方式。
我查看了 ClaimsIdentity 对象 here 的解释,但这并没有真正帮助我理解。
如果我能看到CreateIdentityAsync()
的代码,那可能会有所帮助。
如果我说这一切都错了,请告诉我。否则,如果有人能指出如何生成 ClaimsIdentity 对象,那将会很有帮助。
ClaimsIdentity identity = new ClaimsIdentity
Actor = ????,
BootstrapContext = ?????,
Claims = ?????,
Label = ?????
【问题讨论】:
【参考方案1】:也许following link 可以提供帮助:
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "Brock"));
claims.Add(new Claim(ClaimTypes.Email, "brockallen@gmail.com"));
var id = new ClaimsIdentity(claims,DefaultAuthenticationTypes.ApplicationCookie);
var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignIn(id);
【讨论】:
【参考方案2】:我认为你“做这一切都错了”。 ASP.NET 身份框架在设计时考虑了可插入持久性。将 RavenDB 替换为 EF 的正确方法不是替换 UserManager
。而是实现一个替换UserStore
。所以AccountController
中创建UserManager
的行将从:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
收件人:
public AccountController()
: this(new UserManager<ApplicationUser>(new RavenDBUserStore<ApplicationUser>/* connection info here*/)))
RavenDBUserStore
将是您编写的实现 IUserStore
、IUserPasswordStore
以及您的特定应用程序所需的任何其他 *Store 接口的类。
这种方法避免您需要理解和重新实现 UserManager
中的所有内容,并确保您能够利用 MS 对 UserManager
的未来改进。
有关如何执行此操作的更多信息,请参阅Overview of Custom Storage Providers for ASP.NET Identity 和Implementing a Custom mysql ASP.NET Identity Storage Provider 的示例。您还应该查看他的answer 中提到的David Boike 创建的RavenDB.AspNet.Identity Nuget Package 的代码。源代码在 github 上https://github.com/ILMServices/RavenDB.AspNet.Identity/tree/master/RavenDB.AspNet.Identity
【讨论】:
我相信这是手头问题的正确答案:即“如何使用 Identity 2.0 的不同数据存储”。重新实现你自己的ClaimsIdentity
而不完全理解如何以及为什么只是在寻找麻烦。 +1 用于理解框架的用途【参考方案3】:
这是我想出的。我很想知道这是否是完成这项任务的正确方法。
在一个默认的 MVC5 网站上工作,我去了 Account Controller,找到了SignInAsync()
函数。我调整如下:
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
//var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); --> this is where I want to get rid of UserManager
List<Claim> claims = new List<Claim>
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", user.Name), //user.Name from my database
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", user.Id), //user.Id from my database
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "MyApplication"),
new Claim("FirstName", user.FirstName) //user.FirstName from my database
;
ClaimsIdentity identity = new System.Security.Claims.ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);
AuthenticationManager.SignIn(new AuthenticationProperties() IsPersistent = isPersistent , identity);
请记住,这还需要更改 [HttpPost] Login
函数以从我的数据库中获取用户,而不是使用 UserManager.FindAsync()
函数。
这些调整后,默认站点的登录/注销部分似乎可以正常工作。在我接受之前,我将把这个答案留在这里一段时间,以防有人能告诉我为什么我不应该这样做。
【讨论】:
尽管人们在不完全理解的情况下使用这种方法的后果确实让我感到害怕,但其他人应该查看ClaimTypes
枚举以生成架构 URI:具体而言,ClaimTypes.NameIdentifier
将生成 "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"
等。人。
要扩展这种“方法”的这些“后果”吗?【参考方案4】:
我为新的 ASP.NET MVC 5 标识创建了一个 RavenDB 实现,并将其作为 NuGet 包发布。这可能对你有用。
http://www.nuget.org/packages/RavenDB.AspNet.Identity/
它有点预发布,但我在实际项目中使用它。
这是关于它的GitHub project 和short thread on the RavenDB discussion group。
【讨论】:
以上是关于如何为 Asp.NET MVC 5 创建 ClaimsIdentity 对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 ASP.NET MVC 2 创建自定义成员资格提供程序?
如何为 ASP.NET MVC 处理“未找到 404 页面”查询的全部路由?