More in this section

Forums / General Discussions / Simple example with Custom Membership provider

Simple example with Custom Membership provider

21 posts, 0 answered
  1. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    09 Mar 2011
    Link to this post
    Hello,
    I need to write my own custom membership provider that only needs to replace the ValidateUser method.... I tried using a
    TestProvider : MembershipProvider

    and I can stop at validate user,
    using

    TestProvider : SitefinityMembershipProvider

    I got no luck.......since for what I need I don't have to override all the methods but only one, anyone can provide me a sample? even what to set in web.config and Security.Config (I've tried to add via admin panel but with no luck

    Thanks
    Paolo
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    09 Mar 2011
    Link to this post
    Hello Paolo,

    Please take a look at this post

    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/sdk/extending-membership-provider.aspx

    Best wishes,
    Ivan Dimitrov
    the Telerik team
  3. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    09 Mar 2011
    Link to this post
    Hello Ivan,
     I just looked at that posted before, my question is from which class should I hinerits ? I'll use my custom SQLServer database to validate the user.....so I think I can't use the OpenAccessMembershipProvider, am I right?
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    09 Mar 2011
    Link to this post
    Hello Paolo,

    MembershipDataProvider is the base class. There is OpenAccessMembershipProvider which inherits from MembershipDataProvider.  OpenAccessMembershipProvider is our implementation related to the OA model. If you are not going to use our logic and our database as a storage you can inherit from MembershipDataProvider

    Best wishes,
    Ivan Dimitrov
    the Telerik team
  5. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    09 Mar 2011
    Link to this post
    Hello Ivan,
    thanks a lot, just a question, when I login/logout it executes the

    public override IQueryable<Telerik.Sitefinity.Security.Model.User> GetUsers()
           {
                
               throw new System.NotImplementedException();
           }

    using the OpenData I can set to base.GetUsers(), hineriting from MembershipDataProvider doens't permits to me to do so...any suggestion?

    what should I put in there? I can't set it to null...
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    09 Mar 2011
    Link to this post
    Hello Paolo,

    In your previous post you said that you would use another database to get the users. In this method you should query this external for Sitefinity database.
     
    If the user belong to another database and it is not created through Sitefinity the Validate method should also be rewritten, because it will not work outside of the OA provider.

    Kind regards,
    Ivan Dimitrov
    the Telerik team
  7. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    10 Mar 2011
    Link to this post
    Hello Ivan,
    but the GetUsers method should retrieve all the user that are inside my external DB? I've done a simple test doing :

    public override IQueryable<Telerik.Sitefinity.Security.Model.User> GetUsers()
          {
              IQueryable<Telerik.Sitefinity.Security.Model.User> lst = new List<Telerik.Sitefinity.Security.Model.User>().AsQueryable();
              return lst;
          }
          public override bool ValidateUser(string userName, string password)
          {
              return true;
              int a = 0;
              re

    but when I log in I receive this :

    Invalid user name.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.ArgumentException: Invalid user name.

    Source Error:

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace:

    [ArgumentException: Invalid user name.]
       Telerik.Sitefinity.Security.SecurityManager.AuthenticateUser(String membershipProviderName, String userName, String password, Boolean persistent, User& user) +206
       Telerik.Sitefinity.Security.Web.UI.LoginForm.LoginForm_Authenticate(Object sender, AuthenticateEventArgs e) +189
       System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e) +115
       System.Web.UI.WebControls.Login.AttemptLogin() +127
       System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e) +101
       System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
       System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +125
       System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +169
       System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +9
       System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
       System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +176
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563
    

    any help?
    Thanks
  8. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    10 Mar 2011
    Link to this post
    Hi Paolo,

    Yes you need to query your database in GetUsers method and return a Queriable list of yuor users. Currently you are returning an empty list.Also you should set the login form control to use your custom membership provider. If this is the backend login control you should see a drop down with the two providers inside it.

    Kind regards,
    Ivan Dimitrov
    the Telerik team
  9. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    10 Mar 2011
    Link to this post
    Hello Ivan,
    I don't know if I'm doing something wrong or if it's a bug..... by the way If I do so :

    public override IQueryable<Telerik.Sitefinity.Security.Model.User> GetUsers()
           {
               Stopwatch sw = new Stopwatch();
               sw.Start();
               List<Telerik.Sitefinity.Security.Model.User> lst = new List<Telerik.Sitefinity.Security.Model.User>();
               //using (XXXEntities entities = new XXXEntities())
               //{
               //    Parallel.ForEach(entities.I_UTENTI, (i) =>
               //    {
               //        User user = new User();
               //        user.SetUserName(i.UTENTE.ToUpper());
               //        lst.Add(user);
               //    });
               //}
               //sw.Stop();
               //TimeSpan ts = sw.Elapsed;
               return lst.AsQueryable();
           }

    I got an error.......(Invalid user name)

    I also get this error if I write the username in lowercase when executing the code I wrote you uncommented (going on XXXEntity's I_UTENTI and having the username written in lowercase....... it needs a match on I_UTENTE.UTENTE equals to telerik's logintextbox . text ....

    I've set the memebership provider in the userconrol and I see the two providers (the login control is the one for the fronend users, the backend users will log using the default credentials)

    another question when implementing the providers I saw a

    MembershipManagerInfo and ApplicationName, what should I put in there?

    Thanks
    Paolo

  10. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    10 Mar 2011
    Link to this post
    Hi Paolo,

    You should create a user object and return a list of users

    User newUser = new User {};
     newUser.Comment = "";
     newUser.LastActivityDate = DateTime.UtcNow.AddDays(-1);
     newUser.LastModified = DateTime.MinValue;
     newUser.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
     newUser.FailedPasswordAttemptWindowStart = DateTime.MinValue;
     newUser.LastActivityDate = DateTime.MinValue;
     newUser.LastLoginDate = DateTime.MinValue;
     var mi = new ManagerInfo();
     newUser.SetCreationDate(DateTime.UtcNow);
     newUser.SetLastPasswordChangedDate(DateTime.UtcNow);
     newUser.SetLastLockoutDate(DateTime.UtcNow);
     mi.ApplicationName = newUser.ApplicationName;
     mi.ManagerType = typeof(UserManager).FullName;
     mi.ProviderName = "SampleProvider";
     newUser.ManagerInfo = mi;
     users.Add(newUser);


    Regards,
    Ivan Dimitrov
    the Telerik team
  11. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    10 Mar 2011
    Link to this post
    Hello Ivan,
    I tried but I always get 

    Server Error in '/' Application.

    Invalid user name.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.ArgumentException: Invalid user name.

    Source Error:

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace:

    [ArgumentException: Invalid user name.]
       Telerik.Sitefinity.Security.SecurityManager.AuthenticateUser(String membershipProviderName, String userName, String password, Boolean persistent, User& user) +206
       Telerik.Sitefinity.Security.Web.UI.LoginForm.LoginForm_Authenticate(Object sender, AuthenticateEventArgs e) +189
       System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e) +115
       System.Web.UI.WebControls.Login.AttemptLogin() +127
       System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e) +101
       System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
       System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) +125
       System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +167
       System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
       System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
       System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563
    

    In order to avoid this I need to have in my collection an item with the same name I typed in the textbox....
  12. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    11 Mar 2011
    Link to this post
    Hello Ivan,
    can you please update me on this?
    Thanks
  13. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    11 Mar 2011
    Link to this post
    Hello Paolo,

    This error is thrown when the user does not exist in the datasource. So, the provider name of you use is not correct

    var membershipProviderName = "YOUR PROVIDER NAME";
    var manager = UserManager.GetManager(membershipProviderName);
    manager.Provider.SuppressSecurityChecks = true;
     if (manager.ValidateUser(userName, password))
                {
                    user = manager.GetUser(userName);
                
                    if (user == null)
                        throw new ArgumentException("Invalid user name.");

    Can you run the code below to see whether it will pass. The user should not be null if the provider is correct.

    Best wishes,
    Ivan Dimitrov
    the Telerik team
  14. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    11 Mar 2011
    Link to this post
    I'm to try this now but my get users will return just a dummy username, am I right? as you pasted me below..... or for each user I've in my collection I need to create such an object?

    For my provider name you intend the name of my class?
    Thanks
  15. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    15 Mar 2011
    Link to this post
    Hello Paolo,

    Since you have a custom provider this provider should have a name which you used to register it. Inside manager.ValidateUser you should pass the name and password of the user you are trying to authenticate. This should be an object of type Telerik.Sitefinity.Security.Model.User

    Best wishes,
    Ivan Dimitrov
    the Telerik team
  16. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    21 Mar 2011
    Link to this post
    Hello Ivan,
    I've returned working on this.... I've got my own MembershipProvider and I used successfully to log in, I've tried going in the backend and changing the page permission (I wish to set it to authenticated), when I set it I got a strange problem.....I got the following error :

    A referential integrity constraint violation occurred: A primary key property that is a part of referential integrity constraint cannot be changed when the dependent object is Unchanged unless it is being set to the association's principal object. The principal object must be tracked and not marked for deletion.

    This error happens in the getter of self generated property

    [XmlIgnoreAttribute()]
         [SoapIgnoreAttribute()]
         [DataMemberAttribute()]
         [EdmRelationshipNavigationPropertyAttribute("IModel", "FK_SF_PROFILI_UTENTI_I_UTENTI", "SF_PROFILI_UTENTI")]
         public SF_PROFILI_UTENTI SF_PROFILI_UTENTI
         {
             get
             {
                 return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<SF_PROFILI_UTENTI>("IModel.FK_SF_PROFILI_UTENTI_I_UTENTI", "SF_PROFILI_UTENTI").Value;
             }
             set
             {
                 ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<SF_PROFILI_UTENTI>("IModel.FK_SF_PROFILI_UTENTI_I_UTENTI", "SF_PROFILI_UTENTI").Value = value;
             }
         }

    I defined my RoleProvider as follow :

    public class IFRoleProvider :  RoleDataProvider
      {
          public IFRoleProvider()
          {
              int t = 0;
          }
          public override Telerik.Sitefinity.Security.Model.Role CreateRole(Guid id, string roleName)
          {
              throw new NotImplementedException();
          }
          public override Telerik.Sitefinity.Security.Model.Role CreateRole(string roleName)
          {
              throw new NotImplementedException();
          }
          public override Telerik.Sitefinity.Security.Model.UserLink CreateUserLink(Guid id)
          {
              throw new NotImplementedException();
          }
          public override Telerik.Sitefinity.Security.Model.UserLink CreateUserLink()
          {
              throw new NotImplementedException();
          }
          public override void Delete(Telerik.Sitefinity.Security.Model.UserLink item)
          {
              throw new NotImplementedException();
          }
          public override void Delete(Telerik.Sitefinity.Security.Model.Role item)
          {
              throw new NotImplementedException();
          }
          public override Telerik.Sitefinity.Security.Model.Role GetRole(Guid id)
          {
              throw new NotImplementedException();
          }
          public override IQueryable<Telerik.Sitefinity.Security.Model.Role> GetRoles()
          {
              throw new NotImplementedException();
          }
          public override Telerik.Sitefinity.Security.Model.UserLink GetUserLink(Guid id)
          {
              throw new NotImplementedException();
          }
          public override IQueryable<Telerik.Sitefinity.Security.Model.UserLink> GetUserLinks()
          {
              List<Telerik.Sitefinity.Security.Model.UserLink> lst = new List<Telerik.Sitefinity.Security.Model.UserLink>();
              var l = lst.AsQueryable();
              return l;
          }
      }

    What should I put in there since I don't need to use userlink?
    Thanks
  17. Lubomir Velkov
    Lubomir Velkov avatar
    688 posts
    Registered:
    03 Nov 2014
    24 Mar 2011
    Link to this post
    Hi Paolo,

    Are you using the Microsoft Entiry Framework? It seems to me that the exception comes from it somewhere. We are soon releasing the providers updates so you could simply use our implementation, because there are some specifics that we have tracked and debugged.

    Greetings,
    Liubomir
    the Telerik team
  18. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    31 Mar 2011
    Link to this post
    Hello Ivan,
    yes I'm using EF but I've refactored the tables and now it works... I got problems now with showing the roles in the Administration -> Roles but I've opened another thread

    Thanks
  19. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    04 Apr 2011
    Link to this post
    Hello Ivan,
    when I implement the Membership provider you suggested me to specify a 

    User newUser = GeneraUtenteSF_Da_UtenteIDEA(user);
                     newUser.Comment = string.Empty;
                     newUser.LastActivityDate = DateTime.UtcNow.AddDays(-1);
                     newUser.LastModified = DateTime.MinValue;
                     newUser.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
                     newUser.FailedPasswordAttemptWindowStart = DateTime.MinValue;
                     newUser.LastActivityDate = DateTime.MinValue;
                     newUser.LastLoginDate = DateTime.MinValue;
                     newUser.SetCreationDate(DateTime.UtcNow);
                     newUser.SetLastPasswordChangedDate(DateTime.UtcNow);
                     newUser.SetLastLockoutDate(DateTime.UtcNow);
                     newUser.Id = id;
                     var mi = new ManagerInfo();
                     mi.ApplicationName = newUser.ApplicationName;
                     mi.ManagerType = typeof(UserManager).FullName;
                     mi.ProviderName = "IFProvider";

    ManagerInfo, when I implement the role provider should I use the same manager info or what? I got problem showing the users and their roles in the backoffice (also got problem when setting the role to the one I have in my provider)

    Any suggestion?
    Thanks
  20. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    05 Apr 2011
    Link to this post
    Hi Paolo,

    You have to set the ApplicationName for the role object.

    public override IQueryable<Role> GetRoles()
            {
                var allRoles = this.roleProvider.GetAllRoles();
                var result = new List<RoleWrapper>();
                for (int i = 0; i < allRoles.Length; i++)
                {
                    var newRole = new RoleWrapper(this.id , allRoles[i]);
                    newRole.ApplicationName = this.ApplicationName;
                    result.Add(newRole);
                }

                return result.AsQueryable<Role>();
            }

    public class RoleWrapper : Telerik.Sitefinity.Security.Model.Role
        {
         
            public RoleWrapper(Guid id, string roleName)
            {
                this.Id = id;
                this.Name = roleName;
             
            }
    }

    Regards,
    Ivan Dimitrov
    the Telerik team

  21. Paolo
    Paolo avatar
    147 posts
    Registered:
    11 Jun 2009
    05 Apr 2011
    Link to this post
    Hello Ivan, but should I also set a MembershipInfo to the User / UserLink / Role (I've not got the solution right now...so I remember there's also a ManagerInfo as property.... need I to inherit from RoleManager/UserManager?

    I've also noticed that if I put some Users in the Membership provider for the GetUsers() I got an "Object not set to an instance..."  when I'm in the Admin->Users  section....

    Thanks
21 posts, 0 answered