Custom Role Provider Web Service
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 Blocknamespace 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!
回答
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.
すべての返信
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?
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 WSRoleProvider
ystem.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>- 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. 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 Blocksealed public class WebServiceRoleProvider : System.Web.Security.RoleProvider
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.
- 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.
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.
- Thank you for your response, John. Now that I know 100% that I have to use a wrapper, I'll adjust my code accordingly.


