Odeslat dotazOdeslat dotaz
 

OdpovědětCustom Role Provider Web Service

  • 1. října 2007 20:20Kaleb Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

    I'm trying to implement a custom role provider for my application-base, referenced through a web service. I know this is possible, but I've hit a snag in the implementation of it.

     

    My structure goes as follows:

     

    http://intranet/WebServices/CustomRoleProviderWebService.asmx

    my CustomRoleProviderWebService has the default RoleProvider abstract classes all created and looks like this:

     

     

    Code Block

    namespace WebService

    {

    [WebService(Namespace = "http://intranet/WebServices/")]

    public class CustomRoleProviderWebService : System.Web.Services.WebService

    {

    [WebMethod(Description = "AddUsersToRoles")]

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

    {

    throw new Exception("The method or operation is not implemented.");

    }

    // The rest of the methods are all there... just showing that I have them specified as WebMethods

    }

    }

     

     

     

    In my Application, I have a reference of my WebService called RoleProvider. I can view the service, invoke the methods (even if just to throw the Exception), and for all intents and purposes, it works.

    My web.config is where I'm having troubles.

    Code Block

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

    <providers>

    <clear/>

    <add name="CustomRoleProvider"

    roleProviderUri=http://intranet/WebServices/CustomRoleProviderWebService.asmx

    applicationName="myApplication"

    type="RoleProvider.WebService.CustomRoleProviderWebService"

    />

    </< FONT>providers>

    </< FONT>roleManager>

     

     

    The only thing I get when I try and view a page with the roleprovider defined that way (or any way I can think of other than the right way, obviously) I get a Could not load type 'RoleProvider.WebService.CustomRoleProviderWebService' error message, which will change depending on the type I've defined. I've also tried referencing an external library by providing the classname, AssemblyName to no avail. Please ... what am I doing wrong?

     

    Any help is greatly appreciated!

Odpovědi

  • 5. října 2007 23:14John SaundersMVP, ModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
     Kaleb wrote:

    Right, but I'm wanting to define the role provider class in the web service. At one point, I was able to get the web.config to accept the webservice as the roleprovider, but it threw an error that the webservice wasn't implementing the roleprovider class. And maybe what I'm trying to do is refactor a little too much.

     

    I just got what you're trying to do.

     

    You're confusing the client and the server. In this context, your web application is a client to the web service.

     

    You have added a Web Reference to your web application and called it "RoleProvider". This creates a proxy class called "RoleProvider.CustomRoleProviderWebService" (the namespace "WebService" is irrelevant). This class derives from SoapHttpClientProtocol, not whatever your web service derives from.

     

    The proxy class is not the same thing as the server class, and it never will be. It's just a convenient way for you to call the web service. It's not the web service class itself. Even if you derived your web service class from System.Web.Security.RoleProvider, your proxy class would still derive from SoapHttpClientProtocol.

     

    So, I'm sorry, but you need to use a wrapper.

Všechny reakce

  • 2. října 2007 0:15John SaundersMVP, ModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

    I presume you've seen Custom MembershipProvider and RoleProvider Implementations that use Web Services? How does your code differ from what's in the article?

     

  • 4. října 2007 20:27rgover Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

    Hey, I also implemented the RolerProvider in a web service, but I created a wrapper class around all the web service calls, and made  the wrapper class the Rolw provider. Heres the class

      public class WSRoleProviderTongue Tiedystem.Web.Security.RoleProvider
        {
            private string applicationName;

            public override string ApplicationName
            {
                get { return applicationName; }
                set { applicationName = value; }
            }
            private string providerName;

            public string ProviderName
            {
                get { return providerName; }
                set { providerName = value; }
            }
            public static System.Net.ICredentials GetWSRoleProviderCredentials()
            {
                // credentials are stored as domain,user,pwd
                if (string.IsNullOrEmpty(Properties.Settings.Default.GbtuRoleProviderWebServiceCredentials))
                {
                    string[] credentialString = Properties.Settings.Default.GbtuRoleProviderWebServiceCredentials.Split(',');
                    System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(credentialString[1], credentialString[2], credentialString[0]);
                    return credentials;
               
                }
                // otherwise , use the Default Credentials
                //(delegation works we just need to get rid of the IDS from the config file)
                return System.Net.CredentialCache.DefaultCredentials;

            }
            private VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider GetRoleProviderProxy()
            {
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider ws = new VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider();
                ws.Credentials = GetWSRoleProviderCredentials();
                ws.Url = Properties.Settings.Default.VTU_Web_Applications_Gbtu_RoleProviderServiceProxy_RoleProvider;

                return ws;
            }

            public override void AddUsersToRoles(string[] usernames, string[] roleNames)
            {
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                proxy.AddUsersToRoles( usernames, roleNames,HttpContext.Current.User.Identity.Name);

            }

     

            public override void CreateRole(string roleName)
            {
                throw new Exception("Function Create Role has nort been implemented. Just zap the databse");
                //VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                //proxy.CreateRole(roleName, HttpContext.Current.User.Identity.Name);

            }

            public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
            {
                throw new Exception("Function Delete Role has nort been implemented. Just zap the databse");
             
                //VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                //bool deleted = proxy.DeleteRole(roleName, throwOnPopulatedRole, HttpContext.Current.User.Identity.Name);
                //return deleted;
            }

            public override string[] FindUsersInRole(string roleName, string usernameToMatch)
            {
                throw new Exception("Function FindUsersInRole Role has nort been implemented, if needed we can add it");
             
                //VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                //string[] usersInRoles = proxy.FindUsersInRole(roleName, usernameToMatch);
                //return usersInRoles;
            }

            public override string[] GetAllRoles()
            {
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                string[] roles = proxy.GetAllRoles();
                return roles;

            }

            public override string[] GetRolesForUser(string username)
            {
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                string[] rolesForUser = proxy.GetRolesForUser( username);
                return rolesForUser;

            }

            public string[] GetRolesForUser()
            {
                IPrincipal user = System.Web.HttpContext.Current.User;
                string username = user.Identity.Name;
                string[] rolesForUser = GetRolesForUser(username);
                return rolesForUser;

            }

            public override string[] GetUsersInRole(string roleName)
            {
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                string[] usersInRole = proxy.GetUsersInRole( roleName);
                return usersInRole;

            }
            public  DataSet GetUsersInRoleExtendedInfo(string roleName)
            {
                // the -1 is for consistincey in ddlb values where -1 = nothing
                if (String.IsNullOrEmpty(roleName) || roleName == "-1")
                    return null;
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                DataSet  usersInRole = proxy.GetUsersInRoleExtendedInfo(roleName);
                return usersInRole;

            }
            public DataView GetActiveUsersInRoleExtendedInfo(string roleName)
            {
                DataSet ds = GetUsersInRoleExtendedInfo(roleName);
                DataView dv = ds.Tables[0].DefaultView;
                dv.RowFilter = "Active=true";
                return dv;

            }

            public override bool IsUserInRole(string username, string roleName)
            {
            roleName=roleName.ToLower();
               string[] rolesForUser= GetRolesForUser(username);
               foreach (string userrole in rolesForUser)
               {
                   if (userrole.ToLower() == roleName)
                       return true;
               }
               return false;
              
            }
            public bool IsUserInRole(string roleName)
            {
                IPrincipal user = System.Web.HttpContext.Current.User;
                string username = user.Identity.Name;
                bool isUserInRole = IsUserInRole(username, roleName);
                return isUserInRole;

            }
            public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
            {
                VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                proxy.RemoveUsersFromRoles( usernames, roleNames);
            }
            public void RemoveUserFromRole(string salesEmpUser, string roleName)
            {
                string[] userNames = new string[] { salesEmpUser };
    string[] roleNames= new string[] {roleName};
                RemoveUsersFromRoles(userNames,roleNames);

            }
            public void RemoveUserFromRoles(string[] roleNames)
            {
                IPrincipal user = System.Web.HttpContext.Current.User;
                string username = user.Identity.Name;
                string[] usernames = new string[] { username };
                RemoveUsersFromRoles(usernames, roleNames);


            }

            public override bool RoleExists(string roleName)
            {
                // need to do thios
                throw new Exception("Function IsUserInRole Role has nort been implemented, need to do this");
             
                //VTU.Web_Applications.Gbtu.RoleProviderServiceProxy.RoleProvider proxy = GetRoleProviderProxy();
                //bool roleExists = proxy.RoleExists( roleName);
                //return roleExists;
            }
        }

     

    Then in the web config

    <roleManager enabled="true" defaultProvider="WsRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="30" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All">

    <providers>

    <clear/>

    <add name="WsRoleProvider" type="VTU.Web_Applications.Gbtu.Classes.WSRoleProvider" applicationName="Gtbu"/>

    <add name="WindowsProvider" type="System.Web.Security.WindowsTokenRoleProvider" />

    </providers>

  • 4. října 2007 20:50Kaleb Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Sorry for the delayed response, John;

    The code presented on that page does not implement the RoleProvider Class (unless I'm missing something), which means I can't reference it directly from the web.config, at least not in any way I've found. I've got it setup where I'm implementing a role provider which then calls webservice methods, but I want to be able to just reference the web service as a role provider.
  • 4. října 2007 21:06John SaundersMVP, ModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

     Kaleb wrote:

    The code presented on that page does not implement the RoleProvider Class (unless I'm missing something),

     

    Yeah, I think you're missing something. Did you download the code and look at it?

     

    The role provider class starts like this:

     

    Code Block

      sealed public class WebServiceRoleProvider : System.Web.Security.RoleProvider

     

     

  • 5. října 2007 19:44Kaleb Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

    Right, but I'm wanting to define the role provider class in the web service. At one point, I was able to get the web.config to accept the webservice as the roleprovider, but it threw an error that the webservice wasn't implementing the roleprovider class. And maybe what I'm trying to do is refactor a little too much.

     

    I tried implementing a role provider in my application (as it's done in the CP article), but couldn't get the type specified properly in the web.config (I defined it in a separate project so I could keep my layers segregated - I classify Security as more BLL then Presentation Layer).

     

    Your help is greatly appreciated.

  • 5. října 2007 19:46Kaleb Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    rgover - I believe this implemntation is similar to the CP article as well. I do appreciate you pasting your full source, but I'm trying to take it to the next step and not have to implement the proxy/wrapper class.

     

  • 5. října 2007 23:14John SaundersMVP, ModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
     Kaleb wrote:

    Right, but I'm wanting to define the role provider class in the web service. At one point, I was able to get the web.config to accept the webservice as the roleprovider, but it threw an error that the webservice wasn't implementing the roleprovider class. And maybe what I'm trying to do is refactor a little too much.

     

    I just got what you're trying to do.

     

    You're confusing the client and the server. In this context, your web application is a client to the web service.

     

    You have added a Web Reference to your web application and called it "RoleProvider". This creates a proxy class called "RoleProvider.CustomRoleProviderWebService" (the namespace "WebService" is irrelevant). This class derives from SoapHttpClientProtocol, not whatever your web service derives from.

     

    The proxy class is not the same thing as the server class, and it never will be. It's just a convenient way for you to call the web service. It's not the web service class itself. Even if you derived your web service class from System.Web.Security.RoleProvider, your proxy class would still derive from SoapHttpClientProtocol.

     

    So, I'm sorry, but you need to use a wrapper.

  • 15. října 2007 16:33Kaleb Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Thank you for your response, John. Now that I know 100% that I have to use a wrapper, I'll adjust my code accordingly. Smile