2

У меня есть устаревшее приложение, которое я пытаюсь обновить, чтобы использовать MVC 5 с аутентификацией Owin. Однако я застрял, пытаясь добиться правильной работы проверки безопасности. Вероятно, мне не хватает фундаментальной части головоломки, но я не могу понять, что это такое.MVC 5 SecurityStampValidator с пользовательской аутентификацией и ClaimsIdentity

Во-первых, я не использую Entity Framework. У меня есть существующие пользовательские таблицы, которые я действительно не хочу слишком сильно изменять, поскольку они используются во многих устаревших кодах.

До сих пор я следующее ...

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) 

...

В моей Owin код запуска, у меня есть следующее ...

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 называет эту функцию, чтобы получить текущий securitystamp, с чем это следует сравнивать?

В моем классе 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 

Там нет ничего там о настройке начального securitystamp, и я предполагаю, что там должно быть, но я не знаю, как это сделать. Кажется, для этого не существует какого-либо соответствующего свойства для IUser или ClaimsIdentity.

Я действительно не знаю, что я делаю, так как это первый раз, когда я пытался реализовать аутентификацию на основе аутентификации на основе Asp.net и первый раз, когда я использовал MVC. Любая помощь будет принята с благодарностью. Я могу включить любой другой код, который может иметь значение.

Приношу свои извинения за VB.Net. Кажется, никто не использует VB.Net для такого рода вещей, но я как бы застрял в этом, так как слишком много существующих устаревших кодов для конвертирования. Примеры кода C# являются точными.

ответ

3

У вас действительно отсутствует SecurityStamp на вашем пользователе. Хотя у вас есть IUserSecurityStampStore на вашем SPUserStore классе.

По умолчанию SecurityStampValidator принимает SecurityStamp значение для пользователя из IUserSecurityStampStore.GetSecurityStampAsync(userId).И сравните значение со значением, хранящимся в файле cookie, в претензии типа AspNet.Identity.SecurityStamp. И если значения не совпадают, ваш пользователь выкидывается.

Поэтому, если у вас еще нет SecurityStamp, а затем выключите SecurityStampValidtor.

Или убедитесь, что вы положили случайное значение (по умолчанию это руководство) в в вашей базе данных. И когда вы создаете ClaimsIdentity в CreateIdentityAsync убедитесь, что вы добавляете другой претензии:

claims.Add(New Claim(Constants.DefaultSecurityStampClaimType, user.SecurityStamp)) 

Вы можете посмотреть на исходный код SecurityStampValidatorhere и просто следовать тому, что происходит там, чтобы избежать вашего пользователя выход из системы по неправильной причине.

+1

Спасибо @trailmax, я добавил иск, и теперь он работает. – user1751825

+0

Хороший материал! Рад, что это работает для вас! – trailmax

Смежные вопросы