MembershipProvider和RequiresQuestionAndAnswer

时间:2011-04-12 19:04:13

标签: asp.net passwords membership-provider

我们提供网站模板供客户用作其网站的基础。我们的网站有一个自定义会员提供商。

我们遇到了一位客户提出的问题。客户通过电子邮件向潜在会员发送邀请,并使用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

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解正确,但你不能使用用户 - 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