Asp 2.0 comes with many methods, many of which are encapsulated for us, but this causes our custom space to become smaller and smaller. I have been busy for two weeks and have been trying to rewrite System. Web. Security. SqlMembershipProvider. But I didn't find a solution. I was so excited that I found a solution on asp.net this evening.
For more information, refer to explain. Then explain the problems encountered in the middle.
Step 1:
First download a ProviderToolkitSamples. The download link is as follows:
Http://msdn.microsoft.com/en-us/library/aa478948.aspx.
Because we need to rewrite SqlMembershipProvider, a lot of it will be used. net 2.0 underlying methods, these methods are the first, that is, we cannot directly use them. For example, we need to define the class before: using System. web. the SR will return an error. The error is as follows: 'System. web. SR 'is inaccessible due to its protection level. Since we want to override SqlMembershipProvider, we need to provide all the methods used in this class.
Step 2:
Install ProviderToolkitSamples and find the following four classes in the C: \ Program Files \ ASP. NET Provider Toolkit SQL Samples directory:
SecUtil. cs, SqlConnectionHelper. cs, SQLMembershipProvider. cs, SR. cs. Copy them to the app_code folder of the website project.
Because it already exists. vb assembly, we will. if the cs file is put in the same folder, compilation errors will occur. For solutions, refer to the solution that stores class files in different languages in the App_Code directory of my previous blog.
Also, change SQLMembershipProvider. cs to MySQLMembershipProvider. cs, and modify the class definition as follows:
View plaincopy to clipboardprint?
Public class MySQLMembershipProvider: System. Web. Security. MembershipProvider
{
/////////////////////
}
Public class MySQLMembershipProvider: System. Web. Security. MembershipProvider
{
/////////////////////
}
Step 3:
Redefine a convenient namespace and make some modifications to web. config. My modifications are as follows:
View plaincopy to clipboardprint?
<Add name = "MySQLMembershipProvider"
Type = "MyProviders. MySQLMembershipProvider"
ConnectionStringName = "SiteSqlServer"
EnablePasswordRetrieval = "false"
EnablePasswordReset = "true"
RequiresQuestionAndAnswer = "false"
MinRequiredPasswordLength = "3"
MinRequiredNonalphanumericCharacters = "0"
RequiresUniqueEmail = "false"
PasswordFormat = "Hashed"
ApplicationName = "DotNetNuke"
Description = "using MVPHacksMembershipProvider"/>
<Add name = "MySQLMembershipProvider"
Type = "MyProviders. MySQLMembershipProvider"
ConnectionStringName = "SiteSqlServer"
EnablePasswordRetrieval = "false"
EnablePasswordReset = "true"
RequiresQuestionAndAnswer = "false"
MinRequiredPasswordLength = "3"
MinRequiredNonalphanumericCharacters = "0"
RequiresUniqueEmail = "false"
PasswordFormat = "Hashed"
ApplicationName = "DotNetNuke"
Description = "using MVPHacksMembershipProvider"/>
The namespace shown above is MyProviders, and MyProviders is from the MySQLMembershipProvider. cs File
View plaincopy to clipboardprint?
Namespace MyProviders
{
///////////
}
Namespace MyProviders
{
///////////
}
Modify the membership defaultProvider as follows:
View plaincopy to clipboardprint?
<Membership defaultProvider = "MySQLMembershipProvider" userIsOnlineTimeWindow = "15">
<Membership defaultProvider = "MySQLMembershipProvider" userIsOnlineTimeWindow = "15">
Step 4:
Modify MySQLMembershipProvider. First, let's talk about
Public class MySQLMembershipProvider: System. Web. Security. MembershipProvider {}
The custom MySQLMembershipProvider inherits System. Web. Security. MembershipProvider instead of System. Web. Security. SqlMembershipProvider. However, our code is indeed SqlMembershipProvider, which gives us a full set of custom space. It is exciting to think about it.
My goal in this project is to change the encryption method of an existing project to a 16-bit MD5 encryption method. Once I added an md5 METHOD TO THE MySQLMembershipProvider class, the Code is as follows:
View plaincopy to clipboardprint?
// Note: static method for self-adding md5 passwords
Public static string GetMd5 (string str) // calculate MD5
{
Return System. Web. Security. FormsAuthentication. HashPasswordForStoringInConfigFile (str, "MD5"). ToLower (). Substring (8, 16 );
}
// Note: static method for self-adding md5 passwords
Public static string GetMd5 (string str) // calculate MD5
{
Return System. Web. Security. FormsAuthentication. HashPasswordForStoringInConfigFile (str, "MD5"). ToLower (). Substring (8, 16 );
}
We know that md5 encryption is one-way, which is similar to the Hashed encryption method in SqlMembershipProvider. Therefore, I think that Hashed is directly rewritten to the md5 type, so that the modification workload is greatly reduced as other data remains intact.
Next we will discuss the encryption method. We can find it in the source code.
View plaincopy to clipboardprint?
String salt = GenerateSalt ();
String pass = EncodePassword (password, (int) _ PasswordFormat, salt );
String salt = GenerateSalt ();
String pass = EncodePassword (password, (int) _ PasswordFormat, salt );
This indicates that the encryption method is controlled by the EncodePassword (string pass, int passwordFormat, string salt) method. The following is the modified Code.
View plaincopy to clipboardprint?
Internal string EncodePassword (string pass, int passwordFormat, string salt)
{
If (passwordFormat = 0) // MembershipPasswordFormat. Clear
Return pass;
Byte [] bIn = Encoding. Unicode. GetBytes (pass );
Byte [] bSalt = Convert. FromBase64String (salt );
Byte [] bAll = new byte [bSalt. Length + bIn. Length];
Byte [] bRet = null;
Buffer. BlockCopy (bSalt, 0, bAll, 0, bSalt. Length );
Buffer. BlockCopy (bIn, 0, bAll, bSalt. Length, bIn. Length );
If (passwordFormat = 1)
{// MembershipPasswordFormat. Hashed
HashAlgorithm s = HashAlgorithm. Create (Membership. HashAlgorithmType );
BRet = s. ComputeHash (bAll );
// Manually add
Return GetMd5 (pass );
} Else
{
BRet = EncryptPassword (bAll );
}
Return Convert. ToBase64String (bRet );
}
Internal string EncodePassword (string pass, int passwordFormat, string salt)
{
If (passwordFormat = 0) // MembershipPasswordFormat. Clear
Return pass;
Byte [] bIn = Encoding. Unicode. GetBytes (pass );
Byte [] bSalt = Convert. FromBase64String (salt );
Byte [] bAll = new byte [bSalt. Length + bIn. Length];
Byte [] bRet = null;
Buffer. BlockCopy (bSalt, 0, bAll, 0, bSalt. Length );
Buffer. BlockCopy (bIn, 0, bAll, bSalt. Length, bIn. Length );
If (passwordFormat = 1)
{// MembershipPasswordFormat. Hashed
HashAlgorithm s = HashAlgorithm. Create (Membership. HashAlgorithmType );
BRet = s. ComputeHash (bAll );
// Manually add
Return GetMd5 (pass );
} Else
{
BRet = EncryptPassword (bAll );
}
Return Convert. ToBase64String (bRet );
}
In this way, as long as we use the Hashed Encryption Method When configuring web. config, the MD5 password is obtained.
Step 5
What we need to do is modify the password of the original account in the system.
First, we register a user in DNN. Assume that the account and password we have registered are both testmd5. Then, we can go to the database to check that there is a password
"3a25306bb46a03d6" account. This is the 16-bit md5 password of the new testmd5 password.
We can use the following script to change the host password so that the password becomes testmd5.view plaincopy to clipboardprint?
/*
-- Database Utility ---------------------------------------------------------------------------
Description: Reset a Password in a DotNetNuke database
Author: Tony Tullemans
Date Created: 18.04.2007
Note/s: Before you run this script you must know the UserName and Password of another
Registered DNN user in the database you wish to affect.
Bytes -----------------------------------------------------------------------------------------------
*/
DECLARE @ databaseName VARCHAR (128)
SELECT @ databaseName = DB_NAME ()
PRINT 'reset password in database: '+ @ databaseName
PRINT '-----------------------------' + REPLICATE ('-', DATALENGTH (@ databaseName ));
DECLARE @ knownUserName NVARCHAR (128)
DECLARE @ lostUserName NVARCHAR (128)
DECLARE @ lostUserId NVARCHAR (128)
DECLARE @ knownPassword NVARCHAR (128)
DECLARE @ knownSalt NVARCHAR (128)
SET @ knownUserName = 'host'
SET @ lostUserName = 'testmd5'
SELECT @ knownPassword = Password, @ knownSalt = PasswordSalt
FROM aspnet_Membership
Inner join aspnet_users
ON aspnet_Membership.UserId = aspnet_users.UserId
Where UserName = @ knownUserName;
PRINT''
PRINT 'Known Password for "'+ @ knownUserName +'" is: '+ @ knownPassword
PRINT 'Known Password Salt for "'+ @ knownUserName +'" is: '+ @ knownSalt
SELECT @ lostUserId = aspnet_Membership.UserId
FROM aspnet_Membership
Inner join aspnet_users
ON aspnet_Membership.UserId = aspnet_users.UserId
WHERE UserName = @ lostUserName;
PRINT''
PRINT 'userid for "'+ @ lostUserName +'" is: '+ @ lostUserId
PRINT''
IF (DATALENGTH (@ lostUserName) <= 0 OR @ lostUserName is null)
PRINT 'invalid Lost User name' + @ lostUserName
ELSE BEGIN
IF (DATALENGTH (@ knownUserName) <= 0 OR @ knownUserName is null)
PRINT 'invalid Lost User name' + @ lostUserName
ELSE BEGIN
IF (DATALENGTH (@ knownPassword) <= 0 OR @ knownPassword is null)
PRINT 'invalid Known password' + @ knownPassword
ELSE BEGIN
IF (DATALENGTH (@ knownSalt) <= 0 OR @ knownSalt is null)
PRINT 'invalidknown salt' + @ knownSalt
ELSE BEGIN
PRINT''
PRINT 'before'
SELECT left (UserName, 12) as UserName, aspnet_Membership.UserId, left (Email, 20) as Email, Password, PasswordSalt
FROM aspnet_Membership inner join aspnet_users ON aspnet_Membership.UserId = aspnet_users.UserId
WHERE UserName IN (@ knownUserName, @ lostUserName );
PRINT''
PRINT 'changing Password for User Id: "'+ @ lostUserId +'" to "'+ @ knownPassword + '"'
PRINT''
UPDATE aspnet_Membership
SET Password = @ knownPassword,
PasswordSalt = @ knownSalt
-- SELECT UserId, Password, PasswordSalt
-- FROM aspnet_Membership
WHERE UserId = @ lostUserId;
PRINT''
PRINT 'after'
SELECT left (UserName, 12) as UserName, aspnet_Membership.UserId, left (Email, 20) as Email, Password, PasswordSalt
FROM aspnet_Membership inner join aspnet_users ON aspnet_Membership.UserId = aspnet_users.UserId
WHERE UserName IN (@ knownUserName, @ lostUserName );
END
END
END
END
GO
PRINT''
PRINT '*** end of script ***'
PRINT''
GO
/*
-- Database Utility ---------------------------------------------------------------------------
Description: Reset a Password in a DotNetNuke database
Author: Tony Tullemans
Date Created: 18.04.2007
Note/s: Before you run this script you must know the UserName and Password of another
Registered DNN user in the database you wish to affect.
Bytes -----------------------------------------------------------------------------------------------
*/
DECLARE @ databaseName VARCHAR (128)
SELECT @ databaseName = DB_NAME ()
PRINT 'reset password in database: '+ @ databaseName
PRINT '-----------------------------' + REPLICATE ('-', DATALENGTH (@ databaseName ));
DECLARE @ knownUserName NVARCHAR (128)
DECLARE @ lostUserName NVARCHAR (128)
DECLARE @ lostUserId NVARCHAR (128)
DECLARE @ knownPassword NVARCHAR (128)
DECLARE @ knownSalt NVARCHAR (128)
SET @ knownUserName = 'host'
SET @ lostUserName = 'testmd5'
SELECT @ knownPassword = Password, @ knownSalt = PasswordSalt
FROM aspnet_Membership
Inner join aspnet_users
ON aspnet_Membership.UserId = aspnet_users.UserId
Where UserName = @ knownUserName;
PRINT''
PRINT 'Known Password for "'+ @ knownUserName +'" is: '+ @ knownPassword
PRINT 'Known Password Salt for "'+ @ knownUserName +'" is: '+ @ knownSalt
SELECT @ lostUserId = aspnet_Membership.UserId
FROM aspnet_Membership
Inner join aspnet_users
ON aspnet_Membership.UserId = aspnet_users.UserId
WHERE UserName = @ lostUserName;
PRINT''
PRINT 'userid for "'+ @ lostUserName +'" is: '+ @ lostUserId
PRINT''
IF (DATALENGTH (@ lostUserName) <= 0 OR @ lostUserName is null)
PRINT 'invalid Lost User name' + @ lostUserName
ELSE BEGIN
IF (DATALENGTH (@ knownUserName) <= 0 OR @ knownUserName is null)
PRINT 'invalid Lost User name' + @ lostUserName
ELSE BEGIN
IF (DATALENGTH (@ knownPassword) <= 0 OR @ knownPassword is null)
PRINT 'invalid Known password' + @ knownPassword
ELSE BEGIN
IF (DATALENGTH (@ knownSalt) <= 0 OR @ knownSalt is null)
PRINT 'invalidknown salt' + @ knownSalt
ELSE BEGIN
PRINT''
PRINT 'before'
SELECT left (UserName, 12) as UserName, aspnet_Membership.UserId, left (Email, 20) as Email, Password, PasswordSalt
FROM aspnet_Membership inner join aspnet_users ON aspnet_Membership.UserId = aspnet_users.UserId
WHERE UserName IN (@ knownUserName, @ lostUserName );
PRINT''
PRINT 'changing Password for User Id: "'+ @ lostUserId +'" to "'+ @ knownPassword + '"'
PRINT''
UPDATE aspnet_Membership
SET Password = @ knownPassword,
PasswordSalt = @ knownSalt
-- SELECT UserId, Password, PasswordSalt
-- FROM aspnet_Membership
WHERE UserId = @ lostUserId;
PRINT''
PRINT 'after'
SELECT left (UserName, 12) as UserName, aspnet_Membership.UserId, left (Email, 20) as Email, Password, PasswordSalt
FROM aspnet_Membership inner join aspnet_users ON aspnet_Membership.UserId = aspnet_users.UserId
WHERE UserName IN (@ knownUserName, @ lostUserName );
END
END
END
END
GO
PRINT''
PRINT '*** end of script ***'
PRINT''
GO
The above scripts are quite popular on the Internet and can be found by everyone.
The last step is to change passwordformat in the database to 1, because the default hashed is 1. Now, replace hashed with md5, so it should be 1.
Conclusion
After two weeks of fighting, the problem was finally solved. In fact, the problem was not difficult. Some people had the same problem long ago and had already been solved. It was difficult to find a solution to the problem and how to find resources. Among them, I found that many of them are in English, with few Chinese materials. At this time, I finally reflected the role of English.
Thank you
John, M2Land, never chatting, Niu Ge
This article from the CSDN blog, reproduced please indicate the source: http://blog.csdn.net/xw13106209/archive/2010/01/05/5133690.aspx