【问题标题】:MembershipProvider and RequiresQuestionAndAnswerMembershipProvider 和 RequiresQuestionAndAnswer
【发布时间】:2011-04-12 19:04:13
【问题描述】:

我们为客户提供网站模板,作为他们网站的基础。我们的网站有一个自定义会员服务提供商。

我们遇到了一位客户提出的问题。客户通过电子邮件向潜在会员发送邀请,其中包含登录会员的 URL。在注册期间,他们会设置安全问题/答案。

但是,有时潜在会员会丢失电子邮件(以及密码),但仍会尝试加入网站。

客户要求在注册未完成时允许会员在没有通常的安全问题/答案的情况下重设密码。

很遗憾,MembershipProvider 在请求是否需要问题/答案时没有提供用户名。但是它确实在之前调用了 GetUser()。

为了使此功能正常工作,我向 MembershipProvider 添加了一个方法 (StartingPasswordRecovery) 来标记密码重置处于活动状态,并从 PasswordRecovery 页面中的 OnVerifyingUser 事件调用它。

虽然这段代码有效,但我不相信它非常健壮。

谁能给我指出一个更好的解决方案。

这是我添加到我的会员提供商的相关代码。

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

【问题讨论】:

    标签: asp.net passwords membership-provider


    【解决方案1】:

    我不确定我是否正确理解了您,但是您不能使用 User-Profile 来确定用户是否需要问答吗?

    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
    

    【讨论】:

    • 不幸的是,我不相信这会奏效。我遇到的问题是我正在使用 Microsoft 的密码恢复控件。重置密码时,您没有登录,因此 HttpContext 中没有身份信息。
    • 嗯,我必须承认我仍然不能 100% 了解主要问题在哪里以及您的解决方法是什么。稍微编辑了我的代码,以展示一种无需经过身份验证即可单独制作 RequiresQuestionAndAnswer-Property 的方法,但我认为它不会帮助您跳过 Passwordrecovery-Control 的 VerifyingUser。
    • 好的。我会尽力解释。我正在使用 Microsoft 密码恢复控件。它调用 MembershipProvider.RequiresQuestionAndAnswer() 但不提供有关用户的任何详细信息,但我需要特定于用户的答案。在调试时,我发现密码控件总是在调用 RequiresQuestionAndAnswer 之前调用 GetUser(),所以我缓存了 RequiresQuestionAndAnswer,但这并不可靠。然后,当我发现 OnVerifyingUser() 时,我添加了另一个标志。这一切似乎有点不稳定,所以我希望有人能帮助我。您的 VerifyingUser 代码看起来就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2011-10-06
    相关资源
    最近更新 更多