MSDN > 論壇首頁 > ASMX Web Services and XML Serialization > Custom Role Provider Web Service
發問發問
 

已答覆Custom Role Provider Web Service

  • 2007年10月1日 下午 08:20Kaleb 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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!

解答

  • 2007年10月5日 下午 11:14John SaundersMVP, 版主使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆
     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.

所有回覆

  • 2007年10月2日 上午 12:15John SaundersMVP, 版主使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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?

     

  • 2007年10月4日 下午 08:27rgover 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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>

  • 2007年10月4日 下午 08:50Kaleb 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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.
  • 2007年10月4日 下午 09:06John SaundersMVP, 版主使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

     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

     

     

  • 2007年10月5日 下午 07:44Kaleb 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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.

  • 2007年10月5日 下午 07:46Kaleb 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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.

     

  • 2007年10月5日 下午 11:14John SaundersMVP, 版主使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆
     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.

  • 2007年10月15日 下午 04:33Kaleb 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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