More in this section

Forums / Developing with Sitefinity / Multiple Membership/Role Providers

Multiple Membership/Role Providers

26 posts, 0 answered
  1. Matt
    Matt avatar
    9 posts
    Registered:
    11 Feb 2008
    08 May 2008
    Link to this post

    I have configured the site to use two membership providers, one for the admin and another for public users.

    If i configure a login control to use the public membership provider i can log into the site and view restricted pages ok.
    However  if i want to use calls such as

    Roles.IsUserInRole("Fullmember")
    from within any of the controls (SiteTabstrip.ascx for example) it will always return false as it is checking the roles within the default 'Sitefinity' Provider rather than the 'public' provider.

    I can't see any way to allow me to use 'Public' membership and roles within the public users area of the site and just use the 'Sitefinity' membership and roles for Admin.

    Is there any way I can achieve this?





  2. Vlad
    Vlad avatar
    498 posts
    Registered:
    19 Jun 2017
    09 May 2008
    Link to this post
    Hello Matt,

    When you call:

    Roles.IsUserInRole("Fullmember")

    ... actually you call
    IsUserInRole implementation of the default provider.

    In order to call
    IsUserInRole method for a specific provider, you should use:

    Roles.Providers["MyProvider"].IsUserInRole("Fullmember").


    Fortunately, this scenario
    is foreseen in Sitefinity. Feel free to set your public Membership/Role Providers as default - you should not experience any problems.

    Please let us know if you have additional questions.

    Best wishes,
    Vlad
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  3. Matt
    Matt avatar
    9 posts
    Registered:
    11 Feb 2008
    09 May 2008
    Link to this post
    Hi,

    Thanks for your help, I have managed to solve that particular problem by doing as you suggested and changing the public membership/roles to default.

    However this has presented me with another problem. What I am aiming to do is create a site with three types of users, Annoymous users, trial members and full members. The site will be split in two, a general public area and a members area. Both trial and full members will have access to the members area but some pages may be restricted to full members only (hidden on menu from trial members).

    When I create pages with the option of Anonymous access :Deny the user must logon first to access them. Which seems to work fine, however the permissions section for the page admin only lists roles from the 'Sitefinity' provider, not the public one, so from with in the admin section there does not seem to be away for me to assign access to pages based on roles from the 'public' role provider.

    Is there a way to create this type of site structure with sitefinity or can you can you only have annoymous / full member  structure using the 'everyone' group?

    Matt.
  4. Vlad
    Vlad avatar
    498 posts
    Registered:
    19 Jun 2017
    10 May 2008
    Link to this post
    Hi Matt,

    Unfortunately, in the current version, Pages Permissions could be set only for Sitefinity Role provider, but we have plans to extend them for the other providers in the future.

    Currently, you can use only "Everyone" role, which means every authenticated user no matter from which membership provider he/she is. So you cannot manage this type of security site (anonymous/trial/full) using the out-of-the-box functionality of Sitefinity.
    In order to implement it manually, basically you should do the following:
        - create a custom HttpModule and on PostAuthenticateRequest event implement a handler, which throws 403 (forbidden) http error
    if the requested page is 'full members page' and user does not belongs to the 'Fullmember' role.
        -
    create a custom SiteMapProvider which inherits our CmsSiteMapProvider and override IsAccessibleToUser method, which returns false if page is 'full members page' and user does not belongs to the 'Fullmember' role.

    Also, we can suggest another approach:
    You can use only one pair Membership/Role providers and store all users there. In this case you will have four security zones: Anonymous/Sitefinity users/Trial Members/Full members and you could manage the permissions through Sitefinity Administration.

    Hope this is helpful.

    Greetings,
    Vlad
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  5. Matt
    Matt avatar
    9 posts
    Registered:
    11 Feb 2008
    12 May 2008
    Link to this post
    Hi,

    I'm am a little confused by last reply with regards to implementing the fuctionality manually with a custom HTTP module and site map provider.

    I'm unsure where exacly i would set the permissions for the page. Would I create the trail/full member roles in the 'sitefinity' role provider and assign access to pages based on these two groups.

    Then create the same two groups on the 'public' role provider.

    Then in the custom http and sitemap module,  check the role of the current user (from public role provider) with the roles requred for the page (set in the sitefinity provider)?


     
  6. Vlad
    Vlad avatar
    498 posts
    Registered:
    19 Jun 2017
    12 May 2008
    Link to this post
    Hello Matt,

    Sorry for not being clear enough.

    I meant that you have 2 approaches:

    1. You have 2 pairs membership/role providers - one for CMS users and another for public users. As you already know, you cannot set/check permissions for the second provider roles through Sitefinity UI and API. You can only use the Everyone role to set page View permissions for members pages, but, in order to achieve the full members security zone, you should develop a code for this. For example, you could create a http module to deny access  for non-full members users to full members pages, and custom  CmsSiteMapProvoder to implement a similar logic for links in the navigation controls:
       - Custom Http module sample implementation
      using System; 
      using System.Collections.Generic; 
      using System.Web; 
      using Telerik.Cms.Web; 
      using System.Security.Principal; 
       
      public class CustomHttpModule : IHttpModule 
          public void Init(HttpApplication context) 
          { 
              context.PostAuthenticateRequest += new EventHandler(context_PostAuthenticateRequest); 
          } 
       
          void context_PostAuthenticateRequest(object sender, EventArgs e) 
          { 
              HttpContext context = HttpContext.Current; 
              string appPath = context.Request.ApplicationPath; 
              if (!appPath.EndsWith("/")) 
                  appPath += "/"
              if (context.Request.Path.StartsWith(String.Concat(appPath, "members/fullmembers", UrlHelper.PageExtension), StringComparison.OrdinalIgnoreCase) 
                  && !context.User.IsInRole("fullmembers")) 
              {  
                  throw new HttpException(403, "You have no permissions to view this page"); 
              } 
          } 
       
          public void Dispose() 
          { 
          } 
       

       - Custom CmsSiteMapProvider implemntation
      using System.Web; 
      using Telerik.Cms.Web; 
       
      public class CustomCmsSiteMapProvider : CmsSiteMapProvider 
          public CustomCmsSiteMapProvider() 
          { 
          } 
       
          public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node) 
          { 
              if (!base.IsAccessibleToUser(context, node)) 
                  return false
       
              CmsSiteMapNode cmNode = node as CmsSiteMapNode; 
              if (cmNode != null
              { 
                  if (cmNode.CmsPage.Name.Equals("fullmembers", System.StringComparison.OrdinalIgnoreCase) && !HttpContext.Current.User.IsInRole("fullmembers")) 
                      return false
              } 
              return true
          } 
       

       - changes in the web.config:
      ... 
      <httpModules> 
          <add name="CustomHttpModule" type="CustomHttpModule" /> 
      ... 
       
      <siteMap defaultProvider="CmsSiteMapProvider" enabled="true"
          <providers> 
              <clear/> 
                  <add name="CmsSiteMapProvider" description="Displays Cms Pages" type="CustomCmsSiteMapProvider"/> 
          </providers> 
      </siteMap> 
      ... 
       
    2. You have only 1 pair of membership/role providers. Along with the roles for CMS administration you could create one role for Members and another for Full Members, and set the appropriate page permissions for the members pages. Bare in mind that you should remove Cms Access global permission from the above roles, in order to deny them access to the
      CMS administration area.

    Please let us know if you have additional questions.

    Greetings,

    Vlad

    the Telerik team


    Instantly find answers to your questions at the new Telerik Support Center
  7. Rebecca
    Rebecca avatar
    536 posts
    Registered:
    24 Sep 2012
    12 May 2008
    Link to this post
    Hello Matt,

    Sorry for not being clear enough.

    I meant that you have 2 approaches:

    1. You have 2 pairs membership/role providers - one for CMS users and another for public users. As you already know you cannot set/check permissions for the second provider roles through Sitefinity UI and API. You can only use the Everyone role to set page View permissions for members pages, but, in order to achieve the full members security zone, you should develop a code for this. For example, you could create a http module to deny access  for non-full members users to full members pages, and custom  CmsSiteMapProvoder to implement a similar logic for links in the navigation controls:
       - Custom Http module sample implementation
      using System; 
      using System.Collections.Generic; 
      using System.Web; 
      using Telerik.Cms.Web; 
      using System.Security.Principal; 
       
      public class CustomHttpModule : IHttpModule 
          public void Init(HttpApplication context) 
          { 
              context.PostAuthenticateRequest += new EventHandler(context_PostAuthenticateRequest); 
          } 
       
          void context_PostAuthenticateRequest(object sender, EventArgs e) 
          { 
              HttpContext context = HttpContext.Current; 
              string appPath = context.Request.ApplicationPath; 
              if (!appPath.EndsWith("/")) 
                  appPath += "/"
              if (context.Request.Path.StartsWith(String.Concat(appPath, "members/fullmembers", UrlHelper.PageExtension), StringComparison.OrdinalIgnoreCase) 
                  && !context.User.IsInRole("fullmembers")) 
              {  
                  throw new HttpException(403, "You have no permissions to view this page"); 
              } 
          } 
       
          public void Dispose() 
          { 
          } 
       

       - Custom CmsSiteMapProvider implemntation
      using System.Web; 
      using Telerik.Cms.Web; 
       
      public class CustomCmsSiteMapProvider : CmsSiteMapProvider 
          public CustomCmsSiteMapProvider() 
          { 
          } 
       
          public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node) 
          { 
              if (!base.IsAccessibleToUser(context, node)) 
                  return false
       
              CmsSiteMapNode cmNode = node as CmsSiteMapNode; 
              if (cmNode != null
              { 
                  if (cmNode.CmsPage.Name.Equals("fullmembers", System.StringComparison.OrdinalIgnoreCase) && !HttpContext.Current.User.IsInRole("fullmembers")) 
                      return false
              } 
              return true
          } 
       

       - changes in the web.config:
      ... 
      <httpModules> 
          <add name="CustomHttpModule" type="CustomHttpModule" /> 
      ... 
       
      <siteMap defaultProvider="CmsSiteMapProvider" enabled="true"
          <providers> 
              <clear/> 
                  <add name="CmsSiteMapProvider" description="Displays Cms Pages" type="CustomCmsSiteMapProvider"/> 
          </providers> 
      </siteMap> 
      ... 
       
    2. You have only 1 pair membership/role providers. Along with the roles for CMS administration you could create one role for Members and another for Full Members, and set them appropriate page permissions for the members pages. Bare in mind, that you should remove Cms Access global permission from the above roles, in order to deny them to access Cms administration area.

    Please let us know if you have additional questions.

    Greetings,
    Rebecca
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  8. Christian Calderon
    Christian Calderon avatar
    8 posts
    Registered:
    27 Feb 2006
    22 May 2008
    Link to this post
    "Unfortunately, in the current version, Pages Permissions could be set only for Sitefinity Role provider, but we have plans to extend them for the other providers in the future."

    With all due respect,  This is in my opinion a bug and not a missing feature.
  9. Yasen
    Yasen avatar
    121 posts
    Registered:
    18 May 2013
    23 May 2008
    Link to this post
    Hello Christian Calderon,

    This statement is not correct out of its context, sorry for the misunderstanding. You can set permissions for only one role provider in Sitefinity, and this is what Vlad meant in this quotation.

    You can definitely use your role provider with permissions in Sitefinity, the only limitation is to name the provider "Sitefinity" in the web.config - roles section (actually, I am sure it is not obligatory, but other names should be set a bit more carefully). This does not affect your provider in any way, but helps the Sitefinity User Manager resolve roles and permissions correctly.

    What you cannot do and what Vlad meant is that you cannot set permissions for more than one role provider in a Sitefinity website.

    Right after the SP2 release next week, we'll try and follow the support and forum threads related to the issue and provide a working example project with custom role and membership providers, as well as custom login control.

    Sincerely yours,
    Yasen
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  10. Christian Calderon
    Christian Calderon avatar
    8 posts
    Registered:
    27 Feb 2006
    23 May 2008
    Link to this post
    Thanks for your prompt reply and clarification. I know I can use a custom role provider as  I have created one - however I was restricted top use it in the code-behinds only because I did not want to change the default provider to mine - I will try as you are saying and see if it works well for me.

    Thanks Again
  11. Matt
    Matt avatar
    9 posts
    Registered:
    11 Feb 2008
    23 May 2008
    Link to this post

    I noticed in the documentaion there is a section which covers multiple membership providers and a single role provider.
    "One Membership Provider for Public Users , Other Membership Provider for Admin Users, One Role Provider

    This scenario is also possible. When there is more than one membership provider, one could be used to authenticate the administrators, while the other one - the public users. There could be more than one role and membership providers. However, the relationship membership-role provider is 1 to 1 or 1 to 0. Therefore, one membership provider could be related to no more than one role provider. For example, administrators could be managed by one membership provider which relates to the role provider specifying the administrators. Public users, on the other hand, would be managed by another membership provider and would not have any roles (no role provider). 

    "

    Is it not possible to user two membership providers and share single role provider? For example one membership provider for admin users (sitefinity), one for public users (public) and a shared role provider (Sitefinity)?

  12. Yasen
    Yasen avatar
    121 posts
    Registered:
    18 May 2013
    26 May 2008
    Link to this post
    Hi Matt,

    With the default providers, my answer is no, you cannot use a single role provider to manage users from two membership providers. That is because of the database structure, used with both Sitefinity default providers and ASP.net Sql membership/role providers:

    There are three tables in the database related to membership : telerik_Users, telerik_Roles and telerik_UsersInRoles. You can see the relation between users and roles is "many to many".

    So, when for instance the GetRolesForUser("John") is called, the provider looks up John's ID in the Users table, then checks the corresponding role IDs in the intermediate table and finally checks the role names in the Roles table. This is pretty much the same in the default sql implementation of the ASP.net providers.

    However, with custom providers you can manage multiple membership sources with a single role provider. Of course, you'd have to be very careful with duplicating user names/emails, and synchronization of data. As you probably noticed, user name is considered unique in the role provider's methods so this won't be an easy task.

    All the best,
    Yasen
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  13. SelAromDotNet
    SelAromDotNet avatar
    912 posts
    Registered:
    18 Jul 2012
    02 Jul 2008
    Link to this post
    what if you go ahead and implement two memberships, one for sf and another for the restricted area, then make a separate master page for all pages to which the restricted role are granted access. that way you could implement the "check" logic all throughout the derived pages in that master page by checking right in the page load if they are in the desired role and redirect appropriately out of the section if not.

    would that work? I'm going to be doing something similar to this on my own sitefinity site and this is the best solution I can come up with, and would like to know if anyone from the SF team can give me an idea of what to expect.
  14. Yasen
    Yasen avatar
    121 posts
    Registered:
    18 May 2013
    09 Jul 2008
    Link to this post
    Hi Josh,

    That's a great idea, you should be able to use this technique to control access to different areas of your site. Also, you could use your custom http module or code in the global.asax to check page permissions.

    Greetings,
    Yasen
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  15. SelAromDotNet
    SelAromDotNet avatar
    912 posts
    Registered:
    18 Jul 2012
    09 Jul 2008
    Link to this post
    thank you for your reply but now let me ask you this: is it possible to have both memberships active simultanously? that is, be logged in as an administrator to the sitefinity backend, AND also be logged in as a general user in the separate membership system? this way I can log in and out of the membership system and still have full access to the admin panel...

    so far I haven't been able to accomplish this
  16. Yasen
    Yasen avatar
    121 posts
    Registered:
    18 May 2013
    11 Jul 2008
    Link to this post
    Hi SelArom,

    As far as I know. ASP.NET doesn't support this out of the box. You'll have to provide custom authentication functionality, maybe create another cookie. With two login forms you'll have to be careful which cookie to create in each, and then change the functionality of "logout" buttons and the like. The only way Sitefinity interferes with the ASP.NET authentication is that our login form adds a string (CMS the role provider name) in the cookie data. Then, on post authenticate in the http module we check this string to know which role provider to use for authorization.

    Hope this helps, if you meet any other difficulties, feel free to share with us.

    Greetings,
    Yasen
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  17. SelAromDotNet
    SelAromDotNet avatar
    912 posts
    Registered:
    18 Jul 2012
    11 Jul 2008
    Link to this post
    yeah that's about what I've discovered, because the only way I've found to programmatically login/out users is to use the FormsAuthentication class, but this apparently uses the default provider. Controls like LoginStatus, LoginView, etc also seem to work this way, so even though I'm not logged in as a user on the site, it still shows me as logged in because I'm an administrator in sitefinity backend...

    what if I were to move the sitefinity page to an intranet or something, that way I could manage the site from a different domain and therefore have a different cookie? we wanted to do this for security purposes anyway, would this be a good idea and if so can you point me in the right direction to setting it up?
  18. Yasen
    Yasen avatar
    121 posts
    Registered:
    18 May 2013
    11 Jul 2008
    Link to this post
    Hello SelArom,

    I think it won't be a good idea to move the Sitefinity folder to a different domain.
    You can override/recreate the login/logout controls, for example you could check the ~/Sitefinity/Login.aspx page.
    Here is how the user is validated with the default cms membership provider in the login control:

    void Login1_Authenticate(object sender, AuthenticateEventArgs e) 
        { 
            e.Authenticated = UserManager.Default.ValidateUser(this.Login1.UserName, this.Login1.Password); 
        } 

    And here is how you can authenticate with a membership provider you like:

    void Login1_Authenticate(object sender, AuthenticateEventArgs e) 
      //please note that membership and role providers should have the same name in Sitefinity 
      UserManager man = new UserManager("MyMembershipProvider"); 
      e.Authenticated = man.ValidateUser(this.Login1.UserName, this.Login1.Password); 

    Also there is only one RolePrincipal for each session. It is saved in HttpContext.Current.User and it has a property IsAuthenticated. You have to be careful with controls that interfere with it.

    For instance, you have a cookie for the administration and a cookie for the public part (you can programatically create cookies with different names). If you click the administration "logout" by default this would delete one of the cookies and this would result in setting IsAuthenticated to false, despite the fact the other custom cookie is still existing. What you probably need is to set IsAuthenticated to false only if both cookies are deleted.

    For security reasons you should add some functionality in the global.asax or a custom http module that handles the authentication checks. Because if you do this "cookies" thing you'll be authenticated even if you have only one of the cookies.

    Hope this clarifies things more.

    All the best,
    Yasen
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  19. Yasen
    Yasen avatar
    121 posts
    Registered:
    18 May 2013
    17 Jul 2008
    Link to this post
    Hi Guys,

    If you still have issues with multiple providers, permissions, settings or login forms, please refer to this KB article.

    All the best,
    Yasen
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  20. nogatek
    nogatek avatar
    35 posts
    Registered:
    23 Apr 2008
    08 Sep 2008
    Link to this post
    Hi All,

    I've implemented a second role and membership provider and set it as default (for the public website and a shopping cart admin interface). This is working just fine.

    However, the 'SiteFinity' role and membership provider which I've left unchanged which for the SiteFinity Admin interface is now broken. It authenticates the user just fine, but Personalization is not working.

    See error:

    Index was out of range. Must be non-negative and less than the size of the collection.<br>Parameter name: index

    Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index

    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.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index

    Source Error:

    Line 41:             string loggedInUser = ((TextBox) Login1.FindControl("UserName")).Text;
    Line 42: 
    Line 43:             redirectUrl = PersonalizationManager.DefaultInstance.GetGlobalValue<string>(loggedInUser, GlobalSettingConstants.StartPage);
    Line 44: 
    Line 45:             if (string.IsNullOrEmpty(redirectUrl))

    Source File: d:\Visual Studio 2008\Projects\Navon\Sitefinity\Login.aspx.cs    Line: 43

    When I debug Sitefinity\Login.aspx I can see the provider name is SiteFinity and the logged on user name is correct, however it would seem the system cannot find the Personalization settings for this user?

    The  'data', 'security' and 'cms' settings under the 'telerik' secion in web.config have NOT been changed and it would appear the
    Sitefinity\Login.aspx is using these settings.

    Any ideas what might be causing the Personalization to fail?

    Thanks, Mark



  21. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    18 Sep 2008
    Link to this post
    Hello Mark,

    We apologize for the delay with this response.
    The reason for this error is that in the current version of the CMS, the default provider have to be set to "Sitefinity". In other words, it could be changed because the PersonalizationManager could not work with different provider.
    Starting from the next release, this limitation will be removed. You would be able to set different default provider and this error will not be raised.

    We apologize for the inconvenience caused.

    Best wishes,
    Georgi
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  22. nogatek
    nogatek avatar
    35 posts
    Registered:
    23 Apr 2008
    21 Sep 2008
    Link to this post
    Hi Georgi,

    Thanks for clarifying this. I've found a workaround for now, though will look forward to being able to possibly use another provider in future releases.

    Cheers, Mark
  23. Dave
    Dave avatar
    5 posts
    Registered:
    14 May 2008
    30 Oct 2008
    Link to this post
    I have read the KB article, it was helpful but a bit confusing as the example is for SF to use Active Directory Service, which I do not.  None the less, I seem to have it working with an exception.
    In the SF Administration / Users I can change my provider to SQLProvider.  It will list the SQLProvider users and roles, but the First Name and Last Name fields do not work.  The first name field gets populated with the Username, and the Lastname field is null. 
    Any way around this?
  24. Vlad
    Vlad avatar
    498 posts
    Registered:
    19 Jun 2017
    31 Oct 2008
    Link to this post
    Hello Dave,

    Seems you are right. The ManageProfile control does not work correctly with multiple membership providers, always the default profile provider is used. Sorry for that.
    We will investigate the problem deeper and hopefully will post a solution soon.

    All the best,
    Vlad
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  25. Adam
    Adam avatar
    63 posts
    Registered:
    30 Jan 2008
    21 Mar 2009
    Link to this post
    Vlad,

    Has there been a solution to the ManageProfiel not working for multiple membership providers?   I believe this is the problem I am having... see my other post here:

    http://www.sitefinity.com/support/forums/support-forum-thread/b1043S-bhheth.aspx

    Adam
  26. Adam
    Adam avatar
    63 posts
    Registered:
    30 Jan 2008
    21 Mar 2009
    Link to this post
    I found the solution to the problem where the ManageProfile was using the default provider on this page:

    http://msdn.microsoft.com/en-us/library/d8b58y5d.aspx

    provider   Specifies a provider specific to the property. By default, all properties are managed using the default provider specified for profile properties, but individual properties can also use different providers

    By specifying the provider for each property I was able to get it to save my values for the secondard provider.  I left a better explanation of the solution to my other forum posting found here:  

    http://www.sitefinity.com/support/forums/support-forum-thread/b1043S-bhheth.aspx
Register for webinar
26 posts, 0 answered