我在.NET MVC 5应用程序中工作。我不想使用Entity Framework。我想验证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 = ?????
}
答案 0 :(得分:42)
也许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);
答案 1 :(得分:20)
我认为你已经&#34;这一切都是错的&#34;。 ASP.NET Identity Framework在设计时考虑了可插入的持久性。将RavenDB替换为EF的正确方法不是替换UserManager
。相反,它是实现替换UserStore
。因此,创建AccountController
的{{1}}中的行会改为:
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
以及您的特定应用所需的任何其他* Store接口的类。
此方法可避免您需要了解并重新实施IUserPasswordStore
中的所有内容,并确保您能够利用MS对UserManager
的未来改进。
有关如何执行此操作的详细信息,请参阅Overview of Custom Storage Providers for ASP.NET Identity和Implementing a Custom MySQL ASP.NET Identity Storage Provider的示例。您还应该查看RavenDB.AspNet.Identity Nuget Package中提到的David Boike创建的answer代码。来源位于https://github.com/ILMServices/RavenDB.AspNet.Identity/tree/master/RavenDB.AspNet.Identity
的github上答案 2 :(得分:9)
这是我想出的。我很想知道这是否是完成这项任务的正确方法。
在默认的MVC5网站上工作,我去了帐户控制器,找到了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()
功能。
默认网站的LogIn / LogOff部分在这些调整后似乎工作正常。在我接受之前,我会在这里留下这个答案,以防有人告诉我为什么我不应该这样做。
答案 3 :(得分:6)
我为新的ASP.NET MVC 5 Identity创建了一个RavenDB实现,并将其作为NuGet包发布。这可能适合你。
http://www.nuget.org/packages/RavenDB.AspNet.Identity/
这有点预发布,但我在一个真实的项目中使用它。
以下是关于它的GitHub project和short thread on the RavenDB discussion group。
答案 4 :(得分:0)
我希望我没有在此处发布问题的问题,这不适合评论部分
@Katstevens看起来对您来说很对:我的队友找到了该解决方案并使用了很长时间,因此我也在自己的应用程序中实现了该解决方案,但是由于getUserId无法正常工作,因此我发现了这里的内容,然后在Global.aspx启动方法上将声明添加到我的自定义数据中:
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
CustomPrincipalSerializeModel serializeModel = JsonConvert.DeserializeObject<CustomPrincipalSerializeModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.UserId = serializeModel.UserId;
newUser.UserName = serializeModel.UserName;
newUser.NameFamily = serializeModel.NameFamily;
newUser.IP = serializeModel.IP;
newUser.roles = serializeModel.roles;
HttpContext.Current.User = newUser;
System.Threading.Thread.CurrentPrincipal = newUser;
//Added by myself... (make UserId work as identity.GetUserId())
(newUser.Identity as ClaimsIdentity)?.AddClaims(new List<Claim>{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", authTicket.Name), //user.Name from my database
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", serializeModel.UserId), //user.Id from my database
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "RealEstate"), //MyApplication
});
}
}
是的,但是这样做是对的吗? 数据应该从哪里来,应该从哪里发生?等等.... 数据不可替代吗?和安全吗?