Using standard MySqlMembershipProvider

Posted by Community Admin on 04-Aug-2018 15:08

Using standard MySqlMembershipProvider

All Replies

Posted by Community Admin on 13-Nov-2011 00:00

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


Any ideas?

Posted by Community Admin on 16-Nov-2011 00:00

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,
Lubomir Velkov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 17-Nov-2011 00:00

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

Posted by Community Admin on 18-Nov-2011 00:00

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,
Lubomir Velkov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 18-Nov-2011 00:00

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;
            
        
    

Posted by Community Admin on 18-Nov-2011 00:00

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,
Lubomir Velkov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 18-Nov-2011 00:00

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;
            
        

Posted by Community Admin on 18-Nov-2011 00:00

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,
Lubomir Velkov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

This thread is closed