修改自定义成员资格提供程

时间:2012-12-27 12:13:45

标签: asp.net createuserwizard custom-membershipprovider

我正在尝试使用here中的自定义成员资格提供程序类并且工作得非常好。

但我的问题是我想从此课程中删除密码问题和密码答案。

这是我的web.config文件:

    <?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
   <appSettings>
    <add key="ValidationSettings:UnobtrusiveValidationMode" value="None"/>
    <add key="ApplicationName" value="/>
  </appSettings>
  <connectionStrings>
    <add name="HDIConnectionString" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|HDIMembershipProvider.mdf"/>
  </connectionStrings>
  <system.web>
    <pages>
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </controls>
    </pages>
    <machineKey validationKey="C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" decryptionKey="8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" validation="SHA1"/>
    <!--Custom Membership Provider Configuration-->
    <membership defaultProvider="HDIMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear/>
        <add name="HDIMembershipProvider" type="HDI.AspNet.Membership.HDIMembershipProvider" connectionStringName="HDIConnectionString" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" writeExceptionsToEventLog="false" applicationName="/" passwordFormat="Clear"/>
      </providers>
    </membership>
    <customErrors mode="Off"/>
    <compilation debug="true"/>
  </system.web>
  <system.webServer>
    <defaultDocument>
      <files>
        <clear/>
        <add value="Subscribe.aspx"/>
      </files>
    </defaultDocument>
  </system.webServer>
</configuration>

当我尝试创建没有安全问题和回答的新用户时,它不接受新的用户注册。如果我给他们,那么它就是添加到数据库。

正如我在许多论坛和网站上看到的那样,requiresQuestionAndAnswer="false"这个单独行动并没有成功。

那么如何删除它们呢?

以下是会员提供者类:

 'Adapted from: http://msdn2.microsoft.com/en-us/library/6tc47t75(VS.80).aspx
    Imports System.Configuration
    Imports System.Collections.Specialized
    Imports System.Configuration.Provider
    Imports System.Data.SqlClient
    Imports System.Security.Cryptography
    Imports System.Text
    Imports System.Web.Configuration
    Imports System.Web.Security
    Imports System.Data



    Public NotInheritable Class HDIMembershipProvider
        Inherits MembershipProvider

    #Region "Enums"

        Private Enum FailureType
            Password = 1
            PasswordAnswer = 2
        End Enum

    #End Region



    #Region "Initialization"

        Public Overrides Sub Initialize(ByVal name As String, ByVal config As NameValueCollection)
            If config Is Nothing Then _
              Throw New ArgumentNullException("config")

            If name Is Nothing OrElse name.Length = 0 Then _
              name = "HDIMembershipProvider"

            If String.IsNullOrEmpty(config("description")) Then
                config.Remove("description")
                config.Add("description", "How Do I: Sample Membership provider")
            End If

            ' Initialize the abstract base class.
            MyBase.Initialize(name, config)

            _applicationName = GetConfigValue(config("applicationName"), System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath)
            _maxInvalidPasswordAttempts = Convert.ToInt32(GetConfigValue(config("maxInvalidPasswordAttempts"), "5"))
            _passwordAttemptWindow = Convert.ToInt32(GetConfigValue(config("passwordAttemptWindow"), "10"))
            _minRequiredNonAlphanumericCharacters = Convert.ToInt32(GetConfigValue(config("minRequiredAlphaNumericCharacters"), "1"))
            _minRequiredPasswordLength = Convert.ToInt32(GetConfigValue(config("minRequiredPasswordLength"), "7"))
            _passwordStrengthRegularExpression = Convert.ToString(GetConfigValue(config("passwordStrengthRegularExpression"), String.Empty))
            _enablePasswordReset = Convert.ToBoolean(GetConfigValue(config("enablePasswordReset"), "True"))
            _enablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config("enablePasswordRetrieval"), "True"))
            _requiresQuestionAndAnswer = Convert.ToBoolean(GetConfigValue(config("requiresQuestionAndAnswer"), "False"))
            _requiresUniqueEmail = Convert.ToBoolean(GetConfigValue(config("requiresUniqueEmail"), "True"))

            Dim temp_format As String = config("passwordFormat")
            If temp_format Is Nothing Then
                temp_format = "Hashed"
            End If

            Select Case temp_format
                Case "Hashed"
                    _passwordFormat = MembershipPasswordFormat.Hashed
                Case "Encrypted"
                    _passwordFormat = MembershipPasswordFormat.Encrypted
                Case "Clear"
                    _passwordFormat = MembershipPasswordFormat.Clear
                Case Else
                    Throw New ProviderException("Password format not supported.")
            End Select

            Dim ConnectionStringSettings As ConnectionStringSettings = _
              ConfigurationManager.ConnectionStrings(config("connectionStringName"))

            If ConnectionStringSettings Is Nothing OrElse ConnectionStringSettings.ConnectionString.Trim() = String.Empty Then
                Throw New ProviderException("Connection string cannot be blank.")
            End If

            _sqlConnectionString = ConnectionStringSettings.ConnectionString

            ' Get encryption and decryption key information from the configuration.
            Dim cfg As System.Configuration.Configuration = _
              WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath)
            _machineKey = CType(cfg.GetSection("system.web/machineKey"), MachineKeySection)

            If _machineKey.ValidationKey.Contains("AutoGenerate") Then _
              If PasswordFormat <> MembershipPasswordFormat.Clear Then _
                Throw New ProviderException("Hashed or Encrypted passwords " & _
                                            "are not supported with auto-generated keys.")

        End Sub

        Private Function GetConfigValue(ByVal configValue As String, ByVal defaultValue As String) As String
            If String.IsNullOrEmpty(configValue) Then _
              Return defaultValue

            Return configValue
        End Function

    #End Region

    #Region "Implemented Abstract Methods from MembershipProvider"

        ''' <summary>
        ''' Change the user password.
        ''' </summary>
        ''' <param name="username">UserName</param>
        ''' <param name="oldPwd">Old password.</param>
        ''' <param name="newPwd">New password.</param>
        ''' <returns>T/F if password was changed.</returns>
        Public Overrides Function ChangePassword(ByVal username As String, _
        ByVal oldPwd As String, _
        ByVal newPwd As String) As Boolean

            If Not ValidateUser(username, oldPwd) Then _
              Return False

            Dim args As ValidatePasswordEventArgs = _
              New ValidatePasswordEventArgs(username, newPwd, True)

            OnValidatingPassword(args)

            If args.Cancel Then
                If Not args.FailureInformation Is Nothing Then
                    Throw args.FailureInformation
                Else
                    Throw New Exception("Change password canceled due to New password validation failure.")
                End If
            End If

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("User_ChangePassword", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@password", SqlDbType.NVarChar, 255).Value = EncodePassword(newPwd)
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Try
                _sqlConnection.Open()
                _sqlCommand.ExecuteNonQuery()
            Catch e As SqlException
                'Add exception handling here.
                Return False
            Finally
                _sqlConnection.Close()
            End Try

            Return True

        End Function
        ''' <summary>
        ''' Change the question and answer for a password validation.
        ''' </summary>
        ''' <param name="username">User name.</param>
        ''' <param name="password">Password.</param>
        ''' <param name="newPwdQuestion">New question text.</param>
        ''' <param name="newPwdAnswer">New answer text.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function ChangePasswordQuestionAndAnswer( _
        ByVal username As String, _
        ByVal password As String, _
        ByVal newPwdQuestion As String, _
        ByVal newPwdAnswer As String) As Boolean

            If Not ValidateUser(username, password) Then _
              Return False

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("User_ChangePasswordQuestionAnswer", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@returnValue", SqlDbType.Int, 0).Direction = ParameterDirection.ReturnValue
            _sqlCommand.Parameters.Add("@question", SqlDbType.NVarChar, 255).Value = String.Empty
            _sqlCommand.Parameters.Add("@answer", SqlDbType.NVarChar, 255).Value = String.Empty
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Try
                _sqlConnection.Open()
                _sqlCommand.ExecuteNonQuery()
                If (_sqlCommand.Parameters("@returnValue").Value <> 0) Then
                    Return False
                End If
            Catch e As SqlException
                'Add exception handling here.
                Return False
            Finally
                _sqlConnection.Close()
            End Try

            Return True

        End Function
        ''' <summary>
        ''' Create a new user.
        ''' </summary>
        ''' <param name="username">User name.</param>
        ''' <param name="password">Password.</param>
        ''' <param name="email">Email address.</param>
        ''' <param name="passwordQuestion">Security quesiton for password.</param>
        ''' <param name="passwordAnswer">Security quesiton answer for password.</param>
        ''' <param name="isApproved"></param>
        ''' <param name="userID"></param>
        ''' <param name="status"></param>
        ''' <returns></returns>
        Public Overrides Function CreateUser( _
        ByVal username As String, _
        ByVal password As String, _
        ByVal email As String, _
        ByVal passwordQuestion As String, _
        ByVal passwordAnswer As String, _
        ByVal isApproved As Boolean, _
        ByVal userID As Object, _
        ByRef status As MembershipCreateStatus _
        ) _
        As MembershipUser

            Dim _args As ValidatePasswordEventArgs = _
              New ValidatePasswordEventArgs(username, password, True)

            OnValidatingPassword(_args)

            If _args.Cancel Then
                status = MembershipCreateStatus.InvalidPassword
                Return Nothing
            End If

            If (RequiresUniqueEmail AndAlso (GetUserNameByEmail(email) <> String.Empty)) Then
                status = MembershipCreateStatus.DuplicateEmail
                Return Nothing
            End If

            Dim _membershipUser As MembershipUser = GetUser(username, False)

            If _membershipUser Is Nothing Then
                Dim createDate As DateTime = DateTime.Now

                Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
                Dim _sqlCommand As SqlCommand = New SqlCommand("User_Ins", _sqlConnection)

                _sqlCommand.CommandType = CommandType.StoredProcedure
                _sqlCommand.Parameters.Add("@returnValue", SqlDbType.Int, 0).Direction = ParameterDirection.ReturnValue
                _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
                _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName
                _sqlCommand.Parameters.Add("@password", SqlDbType.NVarChar, 255).Value = EncodePassword(password)
                _sqlCommand.Parameters.Add("@email", SqlDbType.NVarChar, 128).Value = email
                _sqlCommand.Parameters.Add("@passwordQuestion", SqlDbType.NVarChar, 255).Value = String.Empty
                _sqlCommand.Parameters.Add("@passwordAnswer", SqlDbType.NVarChar, 255).Value = String.Empty
                _sqlCommand.Parameters.Add("@isApproved", SqlDbType.Bit).Value = isApproved
                _sqlCommand.Parameters.Add("@comment", SqlDbType.NVarChar, 255).Value = String.Empty

                Try
                    _sqlConnection.Open()

                    _sqlCommand.ExecuteNonQuery()
                    If (_sqlCommand.Parameters("@returnValue").Value = 0) Then
                        status = MembershipCreateStatus.Success
                    Else
                        status = MembershipCreateStatus.UserRejected
                    End If
                Catch e As SqlException
                    'Add exception handling here.

                    status = MembershipCreateStatus.ProviderError
                Finally
                    _sqlConnection.Close()
                End Try

                Return GetUser(username, False)
            Else
                status = MembershipCreateStatus.DuplicateUserName
            End If

            Return Nothing
        End Function
        ''' <summary>
        ''' Delete a user.
        ''' </summary>
        ''' <param name="username">User name.</param>
        ''' <param name="deleteAllRelatedData">Whether to delete all related data.</param>
        ''' <returns>T/F if the user was deleted.</returns>
        Public Overrides Function DeleteUser( _
        ByVal username As String, _
        ByVal deleteAllRelatedData As Boolean _
        ) As Boolean

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("User_Del", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@returnValue", SqlDbType.Int, 0).Direction = ParameterDirection.ReturnValue
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Try
                _sqlConnection.Open()
                _sqlCommand.ExecuteNonQuery()
                If (_sqlCommand.Parameters("@returnValue").Value = 0) Then
                    If deleteAllRelatedData Then
                        ' Process commands to delete all data for the user in the database.
                    End If
                Else
                    Return False
                End If

            Catch e As SqlException
                'Add exception handling here.
            Finally
                _sqlConnection.Close()
            End Try

            Return True

        End Function

        Public Overrides Function UnlockUser( _
        ByVal username As String _
        ) _
        As Boolean

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("User_Unlock", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@returnValue", SqlDbType.Int, 0).Direction = ParameterDirection.ReturnValue
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Dim _rowsAffected As Integer = 0

            Try
                _sqlConnection.Open()

                _sqlCommand.ExecuteNonQuery()
                If (_sqlCommand.Parameters("@returnValue").Value = 0) Then
                    Return False
                End If
            Catch e As SqlException
                'Add exception handling here.
                Return False
            Finally
                _sqlConnection.Close()
            End Try

            Return True

        End Function

        ''' <summary>
        ''' Update the user information.
        ''' </summary>
        ''' <param name="_membershipUser">MembershipUser object containing data.</param>
        Public Overrides Sub UpdateUser(ByVal _membershipUser As MembershipUser)

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("User_Upd", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@email", SqlDbType.NVarChar, 128).Value = _membershipUser.Email
            _sqlCommand.Parameters.Add("@comment", SqlDbType.NVarChar, 255).Value = _membershipUser.Comment
            _sqlCommand.Parameters.Add("@isApproved", SqlDbType.Bit).Value = _membershipUser.IsApproved
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = _membershipUser.UserName
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Try
                _sqlConnection.Open()
                _sqlCommand.ExecuteNonQuery()
            Catch e As SqlException
                'Add exception handling here.
            Finally
                _sqlConnection.Close()
            End Try
        End Sub
        ''' <summary>
        ''' Validate the user based upon username and password.
        ''' </summary>
        ''' <param name="username">User name.</param>
        ''' <param name="password">Password.</param>
        ''' <returns>T/F if the user is valid.</returns>
        Public Overrides Function ValidateUser( _
        ByVal username As String, _
        ByVal password As String _
        ) _
        As Boolean

            Dim _isValid As Boolean = False

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("User_Validate", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Dim _sqlDataReader As SqlDataReader = Nothing
            Dim _isApproved As Boolean = False
            Dim _storedPassword As String = String.Empty

            Try
                _sqlConnection.Open()
                _sqlDataReader = _sqlCommand.ExecuteReader(CommandBehavior.SingleRow)

                If _sqlDataReader.HasRows Then
                    _sqlDataReader.Read()
                    _storedPassword = _sqlDataReader.GetString(0)
                    _isApproved = _sqlDataReader.GetBoolean(1)
                Else
                    Return False
                End If

                _sqlDataReader.Close()

                If CheckPassword(password, _storedPassword) Then
                    If _isApproved Then
                        _isValid = True

                        Dim _sqlUpdateCommand As SqlCommand = New SqlCommand("User_UpdateLoginDate", _sqlConnection)

                        _sqlUpdateCommand.CommandType = CommandType.StoredProcedure
                        _sqlUpdateCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = username
                        _sqlUpdateCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName
                        _sqlUpdateCommand.ExecuteNonQuery()
                    End If
                Else
                    _sqlConnection.Close()
                    UpdateFailureCount(username, FailureType.Password)
                End If
            Catch e As SqlException
                'Add exception handling here.
            Finally
                If Not _sqlDataReader Is Nothing Then _sqlDataReader.Close()
                If Not _sqlConnection Is Nothing And _sqlConnection.State = ConnectionState.Open Then _sqlConnection.Close()
            End Try

            Return _isValid
        End Function
        ''' <summary>
        ''' Find all users matching a search string.
        ''' </summary>
        ''' <param name="usernameToMatch">Search string of user name to match.</param>
        ''' <param name="pageIndex"></param>
        ''' <param name="pageSize"></param>
        ''' <param name="totalRecords">Total records found.</param>
        ''' <returns>Collection of MembershipUser objects.</returns>
        Public Overrides Function FindUsersByName( _
        ByVal usernameToMatch As String, _
        ByVal pageIndex As Integer, _
        ByVal pageSize As Integer, _
        ByRef totalRecords As Integer _
        ) _
        As MembershipUserCollection

            Dim _sqlConnection As SqlConnection = New SqlConnection(_sqlConnectionString)
            Dim _sqlCommand As SqlCommand = New SqlCommand("Users_Sel_ByUserName", _sqlConnection)

            _sqlCommand.CommandType = CommandType.StoredProcedure
            _sqlCommand.Parameters.Add("@username", SqlDbType.NVarChar, 255).Value = usernameToMatch
            _sqlCommand.Parameters.Add("@applicationName", SqlDbType.NVarChar, 255).Value = _applicationName

            Dim _membershipUsers As MembershipUserCollection = New MembershipUserCollection()
            Dim _sqlDataReader As SqlDataReader = Nothing
            Dim _counter As Integer = 0

            Try
                _sqlConnection.Open()
                _sqlDataReader = _sqlCommand.ExecuteReader(CommandBehavior.CloseConnection)

                Dim _startIndex As Integer = pageSize * pageIndex
                Dim _endIndex As Integer = _startIndex + pageSize - 1

                Do While _sqlDataReader.Read()
                    If _counter >= _startIndex Then
                        Dim _membershipUser As MembershipUser = GetUserFromReader(_sqlDataReader)
                        _membershipUsers.Add(_membershipUser)
                    End If

                    If _counter >= _endIndex Then _sqlCommand.Cancel()

                    _counter += 1
                Loop
            Catch e As SqlException
                'Add exception handling here.
            Finally
                If Not _sqlDataReader Is Nothing Then _sqlDataReader.Close()
            End Try

            totalRecords = _counter

            Return _membershipUsers
        End Function

    #Region "Utility Functions"
        ''' <summary>
        ''' Create a MembershipUser object from a data reader.
        ''' </summary>
        ''' <param name="_sqlDataReader">Data reader.</param>
        ''' <returns>MembershipUser object.</returns>
        Private Function GetUserFromReader( _
        ByVal _sqlDataReader As SqlDataReader _
        ) _
        As MembershipUser

            Dim _userID As Object = _sqlDataReader.GetValue(0)
            Dim _username As String = _sqlDataReader.GetString(1)
            Dim _email As String = _sqlDataReader.GetString(2)

            Dim _passwordQuestion As String = String.Empty
            If Not _sqlDataReader.GetValue(3) Is DBNull.Value Then _
              _passwordQuestion = _sqlDataReader.GetString(3)

            Dim _comment As String = String.Empty
            If Not _sqlDataReader.GetValue(4) Is DBNull.Value Then _
              _comment = _sqlDataReader.GetString(4)

            Dim _isApproved As Boolean = _sqlDataReader.GetBoolean(5)
            Dim _isLockedOut As Boolean = _sqlDataReader.GetBoolean(6)
            Dim _creationDate As DateTime = _sqlDataReader.GetDateTime(7)

            Dim _lastLoginDate As DateTime = New DateTime()
            If Not _sqlDataReader.GetValue(8) Is DBNull.Value Then _
              _lastLoginDate = _sqlDataReader.GetDateTime(8)

            Dim _lastActivityDate As DateTime = _sqlDataReader.GetDateTime(9)
            Dim _lastPasswordChangedDate As DateTime = _sqlDataReader.GetDateTime(10)

            Dim _lastLockedOutDate As DateTime = New DateTime()
            If Not _sqlDataReader.GetValue(11) Is DBNull.Value Then _
              _lastLockedOutDate = _sqlDataReader.GetDateTime(11)

            Dim _membershipUser As MembershipUser = New MembershipUser( _
            Me.Name, _
            _username, _
            _userID, _
            _email, _
            _passwordQuestion, _
            _comment, _
            _isApproved, _
            _isLockedOut, _
            _creationDate, _
            _lastLoginDate, _
            _lastActivityDate, _
            _lastPasswordChangedDate, _
            _lastLockedOutDate _
            )

            Return _membershipUser

        End Function      
    End Class

0 个答案:

没有答案