我正在尝试使用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