Using standard MySqlMembershipProvider
Hi all,
has anyone manged to get standard MySqlMembershipProvider working with Sitefinity 4.x.
The problem is, that MySql uses integers as userIDs. Now, if you configure the membershipprovider in the web.config and security.config, and you try to login, you'll get an exception like this:
(German)
[FormatException: GUID muss 32 Ziffern mit 4 Bindestrichen enthalten (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).] System.Guid.TryParseGuidWithNoStyle(String guidString, GuidResult& result) +3914001 System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result) +245 System.Guid.Parse(String input) +73 Telerik.Sitefinity.Security.UserWrapper.CopyFrom(MembershipUser user, String applicationName) +140 Telerik.Sitefinity.Security.MembershipProviderWrapper.GetUser(String userName) +52 Telerik.Sitefinity.Security.UserManager.GetUser(String userName) +25 Telerik.Sitefinity.Security.SecurityManager.AuthenticateUser(String membershipProviderName, String userName, String password, Boolean persistent, User& user) +86 Telerik.Sitefinity.Security.Web.UI.LoginForm.LoginForm_Authenticate(Object sender, AuthenticateEventArgs e) +131 System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e) +115
Hi Michael,
Internally Sitefinity uses GUIDs as unique identifiers for all objects, like content items, users, roles, etc. So you need GUIDs as UserIDs in your provider, otherwise the system simply doesn't have a way to recognise the users.
Greetings,Hi Lubomir,
thanks for your answer. Now, I wrapped the MySQLMembershipProvider into a GUIDMySqlMembershipProvider where I do a GUID-Int32 Mapping in some methods, so Sitefinity can work with GUID and the rest can stick with int.
It looks like this: 1 is transformed to 000000-0000-0000-000-00001 and the same way back.
This provider works in my test app as expected. When I set it up in sitefinity, now it wants me to confirm my license no matter what page I try to load.
Michael
Hello Michael,
This issue with the license, did it appear after you registered your new provider? Is it gone if you remove the custom provider? It doesn't really look like an issue with the provider, most likely some problem with wrong configurations.
Regards,Yes, it's gone when I comment out my provider and comes back when I uncomment it.
The bad thing is that I can't detect the error since there is no error in code. Sintefinty run without exceptions. Just shows the license thing.
Here's my provider code:
web.config:
<add name="CMP" type="CustomMembership.GuidMembershipProvider, CustomMembership, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0a758695755184fb" applicationName="TestSite" description="Default" connectionStringName="dbConnection" writeExceptionsToEventLog="False" autogenerateschema="True" enablePasswordRetrieval="True" enablePasswordReset="True" requiresQuestionAndAnswer="False" requiresUniqueEmail="False" passwordFormat="Clear" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="5" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
MySql.Web.Security;
using
System.Web.Security;
using
System.Collections.Specialized;
namespace
CustomMembership
public
class
GuidMembershipProvider : MembershipProvider
MySQLMembershipProvider root =
new
MySQLMembershipProvider();
public
override
void
Initialize(
string
name, NameValueCollection config)
root.Initialize(name, config);
public
override
string
ApplicationName
get
return
root.ApplicationName;
set
root.ApplicationName = value;
public
override
bool
ChangePassword(
string
username,
string
oldPassword,
string
newPassword)
return
root.ChangePassword(username, oldPassword, newPassword);
public
override
bool
ChangePasswordQuestionAndAnswer(
string
username,
string
password,
string
newPasswordQuestion,
string
newPasswordAnswer)
return
root.ChangePasswordQuestionAndAnswer(username, password, newPasswordQuestion, newPasswordAnswer);
public
override
MembershipUser CreateUser(
string
username,
string
password,
string
email,
string
passwordQuestion,
string
passwordAnswer,
bool
isApproved,
object
providerUserKey,
out
MembershipCreateStatus status)
var u = root.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey,
out
status);
return
ConvertToGuidUser(u);
public
override
bool
DeleteUser(
string
username,
bool
deleteAllRelatedData)
return
root.DeleteUser(username, deleteAllRelatedData);
public
override
bool
EnablePasswordReset
get
return
root.EnablePasswordReset;
public
override
bool
EnablePasswordRetrieval
get
return
root.EnablePasswordRetrieval;
public
override
MembershipUserCollection FindUsersByEmail(
string
emailToMatch,
int
pageIndex,
int
pageSize,
out
int
totalRecords)
var res = FindUsersByEmail(emailToMatch, pageIndex, pageSize,
out
totalRecords);
return
ConvertToGuidUsers(res);
public
override
MembershipUserCollection FindUsersByName(
string
usernameToMatch,
int
pageIndex,
int
pageSize,
out
int
totalRecords)
var res = root.FindUsersByName(usernameToMatch, pageIndex, pageSize,
out
totalRecords);
return
ConvertToGuidUsers(res);
public
override
MembershipUserCollection GetAllUsers(
int
pageIndex,
int
pageSize,
out
int
totalRecords)
var res = root.GetAllUsers(pageIndex, pageSize,
out
totalRecords);
return
ConvertToGuidUsers(res);
public
override
int
GetNumberOfUsersOnline()
return
root.GetNumberOfUsersOnline();
public
override
string
GetPassword(
string
username,
string
answer)
return
root.GetPassword(username, answer);
public
override
MembershipUser GetUser(
string
username,
bool
userIsOnline)
var u = root.GetUser(username, userIsOnline);
return
ConvertToGuidUser(u);
public
override
MembershipUser GetUser(
object
providerUserKey,
bool
userIsOnline)
if
(providerUserKey
is
Guid)
providerUserKey = ConvertToInt32((Guid)providerUserKey);
var u = root.GetUser(providerUserKey, userIsOnline);
return
ConvertToGuidUser(u);
public
override
string
GetUserNameByEmail(
string
email)
return
root.GetUserNameByEmail(email);
public
override
int
MaxInvalidPasswordAttempts
get
return
root.MaxInvalidPasswordAttempts;
public
override
int
MinRequiredNonAlphanumericCharacters
get
return
root.MinRequiredNonAlphanumericCharacters;
public
override
int
MinRequiredPasswordLength
get
return
root.MinRequiredPasswordLength;
public
override
int
PasswordAttemptWindow
get
return
root.PasswordAttemptWindow;
public
override
MembershipPasswordFormat PasswordFormat
get
return
root.PasswordFormat;
public
override
string
PasswordStrengthRegularExpression
get
return
root.PasswordStrengthRegularExpression;
public
override
bool
RequiresQuestionAndAnswer
get
return
root.RequiresQuestionAndAnswer;
public
override
bool
RequiresUniqueEmail
get
return
root.RequiresUniqueEmail;
public
override
string
ResetPassword(
string
username,
string
answer)
return
root.ResetPassword(username, answer);
public
override
bool
UnlockUser(
string
userName)
return
root.UnlockUser(userName);
public
override
void
UpdateUser(MembershipUser user)
var u = user;
if
(u.ProviderUserKey
is
Guid)
u =
new
MembershipUser(u.ProviderName, u.UserName, ConvertToInt32((Guid)u.ProviderUserKey), u.Email, u.PasswordQuestion, u.Comment, u.IsApproved, u.IsLockedOut, u.CreationDate, u.LastLoginDate, u.LastActivityDate, u.LastPasswordChangedDate, u.LastLockoutDate);
root.UpdateUser(u);
public
override
bool
ValidateUser(
string
username,
string
password)
return
root.ValidateUser(username, password);
private
int
ConvertToInt32(Guid guid)
try
string
tmp = guid.ToString(
"N"
);
while
(tmp.StartsWith(
"0"
))
tmp = tmp.Substring(1);
return
int
.Parse(tmp);
catch
(Exception)
return
-1;
private
Guid ConvertToGuid(
int
p)
try
string
tmp =
string
.Format(
"0:D32"
, p);
tmp = tmp.Insert(8,
"-"
).Insert(13,
"-"
).Insert(18,
"-"
).Insert(23,
"-"
);
return
new
Guid(tmp);
catch
(Exception)
return
new
Guid();
private
MembershipUser ConvertToGuidUser(MembershipUser u)
try
object
pk = u.ProviderUserKey;
if
(pk
is
int
)
pk = ConvertToGuid((
int
)u.ProviderUserKey);
return
new
MembershipUser(u.ProviderName, u.UserName, pk, u.Email, u.PasswordQuestion, u.Comment, u.IsApproved, u.IsLockedOut, u.CreationDate, u.LastLoginDate, u.LastActivityDate, u.LastPasswordChangedDate, u.LastLockoutDate);
catch
(Exception)
return
u;
private
MembershipUserCollection ConvertToGuidUsers(MembershipUserCollection res)
try
MembershipUserCollection result =
new
MembershipUserCollection();
foreach
(MembershipUser item
in
res)
result.Add(ConvertToGuidUser(item));
return
result;
catch
(Exception)
return
res;
Hello Michael,
Does the license message appear when you try to login to the backend using this provider? Did you try reapplying the license? Does the error appear after that again?
Regards,Ok, now I figured it out myself. I did not overwrite these two: Now it works!!!! May-be, you guys just share this code...
public
override
string
Description
get
return
root.Description;
public
override
string
Name
get
return
root.Name;
Hi Michael,
Yes, the Name property is quite important and must be overriden. Also you could override the Title property, which could return the same thing as Name. Anyway, I'm glad you solved your problem.
All the best,