Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Greg Fyans 140 posts 342 karma points
    Nov 07, 2012 @ 11:25
    Greg Fyans
    0

    Replacing the Umbraco Role Provider

    Hi,

    I need to replace the role provider in Umbraco with my own. This is due to me having to use an existing database of users/roles for a web application.

    As far as my application is concerned I only need to override 2 methods in the RoleProvider: IsUserInRole and GetAllRoles.

    I've implemented this and changed my web.config role providers section.

    In the Umbraco backoffice, when I go to Members => Roles (it's no longer called Member Groups), GetAllRoles is called as it should be and I can list all my roles. I can also go to Content => Public access, choose role based protection and protect a page with one or all of my roles.

    However, the problem is when the page is published and viewed. It doesn't seem to hit my custom role provider. I don't actually know where it's going, but it is recognising the page is protected and it's taking me to the log-in screen, but no matter what I do it doesn't ever let me see the protected page and it doesn't call my IsUserInRole method.

    Has anyone any experience implementing a custom role provider?

    I've tried implementing umbraco.providers.members.MembersRoleProvider and System.Web.Security.RoleProvider to no avail.

    I hope it's possible to replace the role provider in Umbraco, otherwise I'm screwed :)

    Thanks,
    Greg.

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Nov 07, 2012 @ 11:31
    Richard Soeteman
    0

    Hi Greg,

    I've replaced the role provider multiple times. Did you configure it in the web.config file?

    Cheers,

    Richard

  • Greg Fyans 140 posts 342 karma points
    Nov 07, 2012 @ 11:35
    Greg Fyans
    0

    Yes, like I said it works in the back office. My roles are being listed in the Member's section and I can see them when I protect a page in the Content section.

    It's only when I actually view the site do I have a problem.

     

    <roleManager enabled="true" defaultProvider="AbbottRoleProvider">
          <providers>
            <clear />
            <!--<add name="UmbracoRoleProvider" type="umbraco.providers.members.UmbracoRoleProvider" />-->
            <add name="AbbottRoleProvider" type="Abbott.Providers.AbbottRoleProvider" />
          </providers>
    </roleManager>

     

  • Greg Fyans 140 posts 342 karma points
    Nov 13, 2012 @ 16:28
    Greg Fyans
    0

    Hey,

    I'm still struggling with this. I've basically stripped the role provider down to the bare minimum, so here it is:

    namespace Abbott.PsoriASSESS.Web.code.Providers
    {

        using System;

        using System.Web.Security;

        public class AbbottRoleProvider : RoleProvider

        {

            /// <summary>

            /// Gets the friendly name used to refer to the provider during configuration.

            /// </summary>

            /// <returns>The friendly name used to refer to the provider during configuration.</returns>

            public override string Name

            {

                get

                {

                    return "AbbottRoleProvider";

                }

            }

     

            /// <summary>

            /// Gets or sets the name of the application to store and retrieve role information for.

            /// </summary>

            /// <returns>

            /// The name of the application to store and retrieve role information for.

            /// </returns>

            public override string ApplicationName { get; set; }

     

            /// <summary>

            /// Gets an array of user names in a role where the user name contains the specified user name to match.

            /// </summary>

            /// <returns>

            /// A string array containing the names of all the users where the user name matches <paramref name="usernameToMatch"/> and the user is a member of the specified role.

            /// </returns>

            /// <param name="roleName">The role to search in.</param><param name="usernameToMatch">The user name to search for.</param>

            public override string[] FindUsersInRole(string roleName, string usernameToMatch)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Gets a list of users in the specified role for the configured applicationName.

            /// </summary>

            /// <returns>

            /// A string array containing the names of all the users who are members of the specified role for the configured applicationName.

            /// </returns>

            /// <param name="roleName">The name of the role to get the list of users for.</param>

            public override string[] GetUsersInRole(string roleName)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Gets a list of all the roles for the configured applicationName.

            /// </summary>

            /// <returns>

            /// A string array containing the names of all the roles stored in the data source for the configured applicationName.

            /// </returns>

            public override string[] GetAllRoles()

            {

                return new[] { "Patient", "HCP", "Admin", "SuperAdmin" };

            }

     

            /// <summary>

            /// Gets a value indicating whether the specified user is in the specified role for the configured applicationName.

            /// </summary>

            /// <param name="username">The user name to search for.</param>

            /// <param name="roleName">The role to search in.</param>

            /// <returns>

            /// true if the specified user is in the specified role for the configured applicationName; otherwise, false.

            /// </returns>

            public override bool IsUserInRole(string username, string roleName)

            {

                return true;

            }

     

            /// <summary>

            /// Gets a list of the roles that a specified user is in for the configured applicationName.

            /// </summary>

            /// <returns>

            /// A string array containing the names of all the roles that the specified user is in for the configured applicationName.

            /// </returns>

            /// <param name="username">The user to return a list of roles for.</param>

            public override string[] GetRolesForUser(string username)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Adds a new role to the data source for the configured applicationName.

            /// </summary>

            /// <param name="roleName">The name of the role to create.</param>

            public override void CreateRole(string roleName)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Removes a role from the data source for the configured applicationName.

            /// </summary>

            /// <returns>

            /// true if the role was successfully deleted; otherwise, false.

            /// </returns>

            /// <param name="roleName">The name of the role to delete.</param><param name="throwOnPopulatedRole">If true, throw an exception if <paramref name="roleName"/> has one or more members and do not delete <paramref name="roleName"/>.</param>

            public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Gets a value indicating whether the specified role name already exists in the role data source for the configured applicationName.

            /// </summary>

            /// <returns>

            /// true if the role name already exists in the data source for the configured applicationName; otherwise, false.

            /// </returns>

            /// <param name="roleName">The name of the role to search for in the data source.</param>

            public override bool RoleExists(string roleName)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Adds the specified user names to the specified roles for the configured applicationName.

            /// </summary>

            /// <param name="usernames">A string array of user names to be added to the specified roles. </param><param name="roleNames">A string array of the role names to add the specified user names to.</param>

            public override void AddUsersToRoles(string[] usernames, string[] roleNames)

            {

                throw new NotImplementedException();

            }

     

            /// <summary>

            /// Removes the specified user names from the specified roles for the configured applicationName.

            /// </summary>

            /// <param name="usernames">A string array of user names to be removed from the specified roles. </param><param name="roleNames">A string array of role names to remove the specified user names from.</param>

            public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)

            {

                throw new NotImplementedException();

            }

        }

    }

    And this is my web.config section:

        <roleManager enabled="true" defaultProvider="AbbottRoleProvider">

          <providers>

            <clear />

            <!--<add name="UmbracoRoleProvider" type="umbraco.providers.members.UmbracoRoleProvider" />-->

            <add name="AbbottRoleProvider" type="Abbott.PsoriASSESS.Web.code.Providers.AbbottRoleProvider" />

          </providers>

        </roleManager>

    In the Umbraco dashboard when I expand the Roles tree in Members section, it hits "GetAllRoles", but the front-end/published site never hits "IsUserInRole". I have breakpoints in every method body, but they are never hit on the front-end.

    I'm really stuck here. If it isn't possible, can someone confirm this so I can move on to an alternative solution?

    Thanks,
    Greg. 

  • Dan Patching 31 posts 158 karma points c-trib
    Nov 13, 2012 @ 22:08
    Dan Patching
    0

    I'm not sure it is the reason you are having problems, but looking at my role provider code, I always override the Initialize method.

            ///
            /// The overridden initialization method.
            ///
            ///Name of the role provider.
            ///Collection of configuration settings.
            public override void Initialize(string name, NameValueCollection config)
            {
                // Verify that config isn't null
                if (config == null)
                    throw new ArgumentNullException("config");
    
                // Assign the provider a default name if it doesn't have one
                if (String.IsNullOrEmpty(name))
                    name = "CustomSQLRoleProvider";
    
                // Add a default "description" attribute to config if the
                // attribute doesn’t exist or is empty
                if (string.IsNullOrEmpty(config["description"]))
                {
                    config.Remove("description");
                    config.Add("description", "Custom SQL role provider");
                }
    
                // Call the base class's Initialize method
                base.Initialize(name, config);
    
    
                // Read the role data source. NOTE: Unlike
                // ReadOnlyXmlMembershipProvider, this provider can
                // read the data source at this point because Read-
                // RoleDataStore doesn't call into the role manager
                ReadRoleDataStore();
            }
    
    I have used role providers based on Microsofts sample code successfully in many .NET applications, and Umbraco is just a .NET application, so it should be fine.
    A quick Google pointed me at this:
  • Greg Fyans 140 posts 342 karma points
    Nov 14, 2012 @ 10:17
    Greg Fyans
    0

    Hi Dan,

    I've tried overriding the Initialize previously, but I just tried it again there and the same thing happens, however - it does call Initialize!

    The first time the site loads, my Initialize method is called, it runs through fine and the home page loads. When I click on a role-secured page, it detects it's secured and that I'm not logged-in so it takes me to the log-in page. I log-in, I go back to my role-secured page and it takes me back to the log-in page. It doesn't hit the IsUserInRole method.

    I'm going crazy here. I have my provider and I've set it in the web.config... I'm sure there's nothing else to do!

    Greg

  • Greg Fyans 140 posts 342 karma points
    Nov 14, 2012 @ 12:18
    Greg Fyans
    0

    OK, I think I have this. I'm just working up a solution first before confirming it, but it looks like you can't implement your own role provider without also implementing a membership provider (which is something I was going to do, just later in the project).

    I had a dig through the Umbraco source and library.cs => HasAccess calls CurrentMemberId() which attempts to load the user from the Member's database, which I'm not using.

    So I'm just implementing a membership provider now and hopefully this will sort me out :)

    Edit: Just to confirm, you cannot implement a custom role provider without also implementing a custom membership provider.

    Any questions, Tweet me @gfyans

    Greg.

  • Erez 4 posts 24 karma points
    Mar 20, 2013 @ 10:10
    Erez
    0

    Hi Greg,

    I ran into a same problem as you described,

    I also implimented costum role provider, so I can see all roles from my external system in the umbraco admin

    also I have implimented costum membership provider (with only the ValidateUser()  function )

    but still when user  login to a secure page, though he is validated - he is always being redirected to the login page.

     

    I am also trying to migrate Umbraco with Dynamic CRM , and want to pull the members and  roles from the CRM -

    without the need to store them twice  (in Umbraco also) ,  and  stil keep the ability of Umbraco - "Role based protection"

    I will be gald to hear if it is posssible. and what is the solution you choose in the end.

    I am realy stuck on this one and will really appreciate your help.

    Regards

    Erez


     


     


     


  • Greg Fyans 140 posts 342 karma points
    Mar 21, 2013 @ 09:54
    Greg Fyans
    0

    Hi Erez,

    I think you may need more than ValidateUser.

    Try overriding out the following methods as well, you could just return a new MembershipUser with example details filled out to test:

     

    publicoverrideMembershipUserGetUser(object providerUserKey, bool userIsOnline)
    publicoverrideMembershipUserGetUser(string username, bool userIsOnline)

     return new MembershipUser( ProviderName, patient.Username, patient.PatientId, patient.EmailAddress, null, null, patient.Active, false, patient.DateCreated, patient.LastLoginDate, DateTime.Now, DateTime.Now, DateTime.Now);

     

  • Erez 4 posts 24 karma points
    Mar 21, 2013 @ 10:06
    Erez
    0

    Hi Greg,

    Thank you very much for your reply - I figured that out yesterday...

    I have implimented those functions and it solved the problem.

    Thanks again

    Erez



  • Robert J. Bullock 386 posts 405 karma points
    Mar 20, 2014 @ 20:36
    Robert J. Bullock
    0

    I realize this thread is a bit old, but I'm stuck with the same exact problem! Does anyone have any documentation or an example of how to overcome it?

    Robert

  • John Hodgkinson 613 posts 355 karma points
    Apr 08, 2014 @ 10:39
    John Hodgkinson
    0

    Erez- would you by chance please post your solution? We're looking to do what you did but with a netFORUM CRM. many, many thanks in advance!

  • Ryios 122 posts 263 karma points
    Jan 12, 2015 @ 09:13
    Ryios
    0

    Ok, we had to implement a MembershipProvider and a RoleProvider as well. On top of that we had to comment out the UmbracoMembersMembershipProvider and UmbracoRoleProvider and give ours the same name.

    In the back office this changes the look and feel of the Members section to now just show "All Members" and Member Groups (a member group is a role).

    Forcing us to only be able to secure pages on Roles and not individual users (our users don't show up when using individual users).

    It works, but is less than ideal... Eventually I'll try to come up with a way to completely replace umbracos user management and page access checking to support WIF and claims authentication.

Please Sign in or register to post replies

Write your reply to:

Draft