33

我正在使用 .NET MVC 5 应用程序。我不想使用实体框架。我想对 RavenDB 数据库进行身份验证。在我看来,我想替换UserManagerAccount Controller 附带的那个。我想我可以重写所有 UserManager 函数来使用我的数据库,除了我不理解这个ClaimsIdentity对象。

在该SignInAsync方法中,调用了UserManager.CreateIdentityAsync(...). 我知道它返回一个ClaimsIdentity对象。我不知道如何自己创建一个 ClaimsIdentity 对象。

我看到它有 4 个属性ActorBootstrapContext和。我不知道这些属性是做什么用的,也不知道如何正确生成它们。我认为正确生成它们很重要,因为它是身份验证 cookie 的制作方式。ClaimsLabel

我在这里查看了 ClaimsIdentity 对象的解释,但这并没有真正帮助我理解。

如果我能看到 的代码CreateIdentityAsync(),那可能会有所帮助。

如果我对这一切都错了,请告诉我。否则,如果有人能指出如何生成 ClaimsIdentity 对象,那将很有帮助。

ClaimsIdentity identity = new ClaimsIdentity
{
    Actor = ????,
    BootstrapContext = ?????,
    Claims = ?????,
    Label = ?????
}
4

4 回答 4

53

也许以下链接可以提供帮助:

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);
于 2013-12-05T13:03:41.673 回答
20

我认为你“这一切都错了”。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将是您编写的已实现的类IUserStoreIUserPasswordStore以及您的特定应用程序所需的任何其他 *Store 接口。

这种方法避免了您需要了解和重新实现所有内容,UserManager并确保您能够利用未来对UserManager来自 MS 的改进。

有关如何执行此操作的更多信息,请参阅ASP.NET 身份的自定义存储提供程序概述和实施自定义 MySQL ASP.NET 身份存储提供程序的示例。您还应该查看David Boike在他的回答中提到的RavenDB.AspNet.Identity Nuget 包的代码。源代码在 github 上https://github.com/ILMServices/RavenDB.AspNet.Identity/tree/master/RavenDB.AspNet.Identity

于 2014-05-15T16:53:38.700 回答
9

这是我想出的。我很想知道这是否是完成这项任务的正确方法。

在默认的 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()函数。

在这些调整之后,默认站点的登录/注销部分似乎可以正常工作。在我接受它之前,我会在这里留下这个答案一段时间,以防有人能告诉我为什么我不应该这样做。

于 2013-12-05T08:16:21.223 回答
6

I created a RavenDB implementation for the new ASP.NET MVC 5 Identity and released it as a NuGet package. This might work for you.

http://www.nuget.org/packages/RavenDB.AspNet.Identity/

It's somewhat prerelease but I am using it in a real project.

Here's the GitHub project and a short thread on the RavenDB discussion group about it.

于 2013-12-05T18:21:22.177 回答