我有一个遗留的应用程序,我试图更新使用MVC 5与Owin身份验证。然而,我一直在试图让SecurityStamp验证正确工作。我可能错过了一些基本的拼图,但我不知道它是什么。
首先,我不使用实体框架。我有现有的用户表,我真的不想修改太多,因为它们在许多遗留代码中使用。
到目前为止,我有以下内容…
Public Class SPUser
Implements IUser(Of String)
…
Public Class SPUserStore
Implements IUserStore(Of SPUser)
Implements IUserPasswordStore(Of SPUser)
Implements IUserRoleStore(Of SPUser)
Implements IUserSecurityStampStore(Of SPUser)
…
Public Class SPUserManager
Inherits UserManager(Of SPUser)
…
在我自己的启动代码中,我有以下内容…
app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
.AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
.LoginPath = New PathString(url.Action("login", "auth")),
.ExpireTimeSpan = TimeSpan.FromMinutes(10),
.SlidingExpiration = True,
.Provider = New CookieAuthenticationProvider() With {
.OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(
validateInterval:=TimeSpan.FromMinutes(2),
regenerateIdentityCallback:=Function(manager As SPUserManager, user As SPUser)
Return manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)
End Function,
getUserIdCallback:=Function(claimsIdentity)
Return claimsIdentity.FindFirstValue(ClaimTypes.Sid).ToString
End Function)
}
我的用户身份验证工作正常,我的身份验证控制器能够登录用户等。然而,我被卡住的地方是在validateInterval(2分钟)之后,用户被自动踢掉。
我知道它需要检查SecurityStamp。在我的SPUserStore中,我实现了以下方法…
Public Function GetSecurityStampAsync(user As SPUser) As Task(Of String) Implements IUserSecurityStampStore(Of SPUser, String).GetSecurityStampAsync
Return Task.Run(Function()
Return user.Id
End Function)
End Function
目前我的计划只是让securitystamp验证总是通过,然后稍后我将对其进行更改,以根据上次修改的用户表时间戳创建securitystamp。
在调试器中,我可以看到这个函数在2分钟后被调用,但是它总是失败验证。当Owin调用这个函数来获取当前的安全戳时,它应该将其与什么进行比较?
在我的SPUserManager类中,我有以下函数来创建索赔标识…
Public Overrides Function CreateIdentityAsync(user As SPUser, authenticationType As String) As Task(Of ClaimsIdentity)
Return Task.Run(Function()
Dim claims As New List(Of Claim)
claims.Add(New Claim(ClaimTypes.Sid, user.Id.ToString))
claims.Add(New Claim(ClaimTypes.NameIdentifier, user.UserName))
claims.Add(New Claim(ClaimTypes.GivenName, user.FirstName))
claims.Add(New Claim(ClaimTypes.Surname, user.LastName))
Dim identity As New ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie)
Return identity
End Function)
End Function
里面没有关于设置初始安全戳的内容,我猜应该有,但是我不知道怎么做。在IUser或ClaimsIdentity上似乎没有任何相关的属性。
我真的不知道我在做什么,因为这是我第一次尝试实现Asp.net基于身份验证和我第一次使用MVC。任何帮助都将非常感激。我可以包括任何其他相关的代码。
我为VB.Net道歉。似乎没有人使用VB。Net用于这类事情,但我有点被它困住了,因为有太多现有的遗留代码要转换。
您的用户确实缺少SecurityStamp
。虽然你的SPUserStore
课上有IUserSecurityStampStore
默认SecurityStampValidator
从IUserSecurityStampStore.GetSecurityStampAsync(userId)
中获取用户的SecurityStamp
值。并将该值与存储在类型为AspNet.Identity.SecurityStamp
的Claim中的cookie中的值进行比较。如果值不匹配,您的用户将被踢出。
所以如果你还没有在用户上实现SecurityStamp
,那么关闭SecurityStampValidtor
。
或者确保将一个随机值(默认情况下是guid)放入数据库中的user.SecurityStamp
中。当你在CreateIdentityAsync
中创建ClaimsIdentity
时,确保你添加了另一个声明:
claims.Add(New Claim(Constants.DefaultSecurityStampClaimType, user.SecurityStamp))
你可以在这里查看SecurityStampValidator
源代码,并遵循那里发生的事情,以避免用户因错误的原因退出。