MembershipProvider и RequiresQuestionAndAnswer

Мы предоставляем нашим клиентам шаблон веб-сайта для использования в качестве основы для своих веб-сайтов. На нашем веб-сайте есть индивидуальный поставщик членства.

У нас возникла проблема, которую поднял один клиент. Клиент рассылает приглашения потенциальным участникам по электронной почте с URL-адресом для входа в систему. При регистрации они задают свой секретный вопрос / ответ.

Однако иногда потенциальный участник теряет электронную почту (и, следовательно, свой пароль), но все же пытается присоединиться к сайту.

Клиент попросил, чтобы участнику было разрешено сбросить свой пароль без обычного контрольного вопроса / ответа, когда регистрация не была завершена.

К сожалению, MembershipProvider не предоставляет имя пользователя при запросе, требуется ли вопрос / ответ. Однако непосредственно перед этим он вызывает GetUser ().

Чтобы эта функция заработала, я добавил в свой MembershipProvider метод (StartingPasswordRecovery), чтобы отметить, что сброс пароля активен, вызвав его из события OnVerifyingUser на странице PasswordRecovery.

Хотя этот код работает, я не уверен, что он очень надежный.

Может ли кто-нибудь указать мне на лучшее решение.

Вот соответствующий код, который я добавил к поставщику членства.

Private _hasUserDefinedQuestionAndAnswer As Boolean
Private _isResettingPassword As Boolean

Public Overloads Overrides Function GetUser(ByVal username As String, ByVal userIsOnline As Boolean) As System.Web.Security.MembershipUser
    ...
    _hasUserDefinedQuestionAndAnswer = ...
    ... 
End Function

Public Overrides ReadOnly Property RequiresQuestionAndAnswer() As Boolean
    Get
        If Me._isResettingPassword Then
            Me._isResettingPassword = False
            Return Me.pRequiresQuestionAndAnswer And Me._hasUserDefinedQuestionAndAnswer
        End If

        Return Me.pRequiresQuestionAndAnswer
    End Get
End Property

Public Sub StartingPasswordRecovery()
    Me._isResettingPassword = True
End Sub

person sixeyes    schedule 12.04.2011    source источник


Ответы (1)


Я не уверен, правильно ли я вас понял, но не могли бы вы использовать User- Профиль, чтобы определить, нужны ли пользователю вопросы и ответы?

web.config:

<profile defaultProvider="YourProfileProvider">
    <providers>
        <clear/>
        <add name="YourProfileProvider" type="System.Web.Profile.SqlProfileProvider"  connectionStringName="ConnectionStringToDB" applicationName="/YourApp"></add>
    </providers>
    <properties>
        <add name="RequiresQuestionAndAnswer" defaultValue="false" />
    </properties>
</profile>

Пользовательский поставщик членства:

Public Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
    Get
        If HttpContext.Current.User.Identity.IsAuthenticated Then
            Dim userRequiresQuestionAndAnswer = _
                CType(HttpContext.Current.Profile.GetPropertyValue("RequiresQuestionAndAnswer"), Boolean)
            Return userRequiresQuestionAndAnswer
        Else
            Return MyBase.RequiresQuestionAndAnswer 
        End If
    End Get
End Property

Вы можете установить его на своей странице управления пользователями для каждого пользователя индивидуально:

HttpContext.Current.Profile.SetPropertyValue("RequiresQuestionAndAnswer", userRequiresQuestionAndAnswer)
HttpContext.Current.Profile.Save()

Изменить:

согласно вашему комментарию, я немного изменил код. Я надеюсь, что это поможет заставить его работать:

в настраиваемом членстве-провайдере:

Public Overloads Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
    Get
        If HttpContext.Current.User.Identity.IsAuthenticated Then
            Return RequiresQuestionAndAnswer(Membership.GetUser.UserName)
        Else
            Return MyBase.RequiresQuestionAndAnswer
        End If
    End Get
End Property

Public Overloads ReadOnly Property RequiresQuestionAndAnswer(ByVal userName As String) As Boolean
    Get
        Dim profile As ProfileBase = ProfileBase.Create(userName)
        If Not profile Is Nothing Then
            Dim userRequiresQuestionAndAnswer = _
                CType(profile.GetPropertyValue("RequiresQuestionAndAnswer"), Boolean)
            Return userRequiresQuestionAndAnswer
        Else
            Return MyBase.RequiresQuestionAndAnswer
        End If
    End Get
End Property

где находится ваш PasswordRecovery-Control:

Protected Sub VerifyingUser(ByVal sender As Object, ByVal e As LoginCancelEventArgs)
    Dim login As WebControls.Login = DirectCast(Me.LoginView1.FindControl("Login1"), WebControls.Login)
    Dim userName = DirectCast(login.FindControl("PwdRecovery"), PasswordRecovery).UserName
    Dim RequiresQuestionAndAnswer = DirectCast(Membership.Provider, YourMembershipProvider).RequiresQuestionAndAnswer(userName)
    '....'
End Sub
person Tim Schmelter    schedule 12.04.2011
comment
К сожалению, я не верю, что это сработает. У меня проблема в том, что я использую средство восстановления пароля Microsoft. При сбросе пароля вы не вошли в систему, поэтому в HttpContext нет идентификационной информации. - person sixeyes; 13.04.2011
comment
Хм, я должен признать, что до сих пор не понимаю на 100%, в чем заключается основная проблема и что делает ваш обходной путь. Немного отредактировал свой код, чтобы показать способ сделать RequiresQuestionAndAnswer-Property индивидуально без аутентификации, но я не думаю, что это поможет вам пропустить VerifyingUser из Passwordrecovery-Control. - person Tim Schmelter; 13.04.2011
comment
В ПОРЯДКЕ. Я постараюсь объяснить. Я использую средство восстановления пароля Microsoft. Он вызывает MembershipProvider.RequiresQuestionAndAnswer (), но не предоставляет никаких сведений о пользователе, но мне нужен ответ для конкретного пользователя. Во время отладки я обнаружил, что элемент управления паролем всегда вызывает GetUser () непосредственно перед вызовом RequiresQuestionAndAnswer, поэтому я кэшировал RequiresQuestionAndAnswer, но это было ненадежно. Затем я добавил еще один флаг, когда обнаружил OnVerifyingUser (). Все это кажется немного ненадежным, поэтому я надеялся, что кто-нибудь может мне помочь. Ваш код VerifyingUser выглядит именно так. - person sixeyes; 14.04.2011