Using a custom role provider with CSLA 3.6.2

Using a custom role provider with CSLA 3.6.2

Old forum URL: forums.lhotka.net/forums/t/7421.aspx


GregJ posted on Friday, August 07, 2009

I would like to use a custom InRoleProvider with CSLA. Specifically, I would like to use the static 'IsUserInRole()' method of the 'System.Web.Security.Roles' class, located in the 'System.Web.dll' assembly.

In the latest documentation (bottom of page 363) it states that "If the application’s config file contains an entry for an IsInRoleProvider() method, that method is used instead of the default."

The example given is:

<add key="CslaIsInRoleProvider" value="Namespace.Class.Method,Assembly" />

This example doesn't seem to provide the correct format for the 'value' attribute. I tried the following and it didn't work.

<add key="CslaIsInRoleProvider" value="System.Web.Security.Roles.IsUserInRole,System.Web" />

The above configuration produces the exception:

System.IndexOutOfRangeException : Index was outside the bounds of the array.

When I step through the code I find that there is a call to the static 'IsInRole()' method of 'AuthorizationRulesManager'. Within that method my configured provider value "System.Web.Security.Roles.IsUserInRole,System.Web" gets converted to an array by splitting on the comma, producing an array with a length of 2. On the following line the two array elements are joined back together with a call to MethodCaller.GetType(), which in turn delegates to Type.GetType():

string[] items = provider.Split(',');
Type containingType = Csla.Reflection.MethodCaller.GetType(items[0] + "," + items[1]);
mIsInRoleProvider = (IsInRoleProvider)(Delegate.CreateDelegate(typeof(IsInRoleProvider), containingType, items[2]));

Two things seem to be wrong:

First, the .NET Framework method Type.GetType(typeName) requires an assembly-qualified name for the typeName argument. An assembly-qualified name evidently has to be of the format:

"System.Web.Security.Roles, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

I wrote the following test code and found that only the first statement resulted in an object, the rest returned null:

Type theType1 = Type.GetType("System.Web.Security.Roles, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
Type theType2 = Type.GetType("System.Web.Security.Roles, System.Web, Version=2.0.0.0, Culture=neutral");
Type theType3 = Type.GetType("System.Web.Security.Roles, System.Web, Version=2.0.0.0");
Type theType4 = Type.GetType("System.Web.Security.Roles, System.Web");

Second, notice that in the previous code sample the call to CreateDelegate() expects a third element in the array created from the provider string. How can there be a third element if there is only one comma?

Has anyone else tried this?

Thanks,
Greg


 

RockfordLhotka replied on Saturday, August 08, 2009

Type.GetType() doesn't always require a fully qualified assembly name - it depends on the assembly you are trying to reference and where it is found.

This feature was designed for you to create the method in your assembly. And if you don't sign you assembly, it can be found simply by name as long as it is in the assembly search path.

However, System.Web is signed, and it is in the GAC, two things that make you use the longer assembly name.

You could be right about the 3 parameters. I'm in the middle of in installing Win7 though, so I don't have easy access to the code. If it really is 3 parameters, it is probably something like:

type, assembly, method

 

GregJ replied on Tuesday, August 18, 2009

Okay. Well, then the next question would be how to specify a fully qualified assembly name (with its embedded commas) in the configuration file and have it "split" properly when read by the code. If that's not possible I guess the next tactic would be to write a custom un-strongnamed assembly as a wrapper that delegates to the method in the Framework assembly so it will be compatible with the configuration design.

Actually, the whole reason I'm wanting to use the System.Web.Security.Roles class is that I ultimately want to use AzMan (Windows Authorization Manager) as my role management provider. Since CSLA doesn't provide direct support for AzMan I want to use ASP.NET role management with its role manager provider configured as AzMan.

Like this:

<connectionStrings>
  <
clear
/>
  <
add name="AzManPolicyStores" connectionString="msxml://path/to/AzManPolicyStores.xml" providerName=""
/>
</
connectionStrings
>

<system.web>
  <
roleManager enabled="true" defaultProvider="AzManRoleProvider"
>
    <
providers
>
    <
clear
/>
    <
add name="AzManRoleProvider" type="System.Web.Security.AuthorizationStoreRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, publicKeyToken=b03f5f7f11d50a3a" connectionStringName="AzManPolicyStores" applicationName="MyApplication"
/>
    </
providers
>
  </
roleManager
>
</
system.web
>

RockfordLhotka replied on Monday, August 31, 2009

I see what you are saying, and that's an oversight.

I made up this scheme for identifying a static method - there is no standard for this. In retrospect I probably should have forced you to add two elements to appSettings, one to identify the type, the other to identify the method name...

I'll add this to the bug list, but I'm busy so it won't happen soon (and maybe not in the version of CSLA you are using depending on how old it is), so you might want to change the code in ApplicationSettings (or whereever) that parses this value to make it work in the meantime.

tiago replied on Sunday, November 08, 2009

RockfordLhotka:

I see what you are saying, and that's an oversight.

I made up this scheme for identifying a static method - there is no standard for this. In retrospect I probably should have forced you to add two elements to appSettings, one to identify the type, the other to identify the method name...

I'll add this to the bug list, but I'm busy so it won't happen soon (and maybe not in the version of CSLA you are using depending on how old it is), so you might want to change the code in ApplicationSettings (or whereever) that parses this value to make it work in the meantime.

Hi Rocky,

Is this issue solved?

GregJ replied on Sunday, November 08, 2009

As far as I know, it is not resolved. However, I elected to implement a different solution rather than wait for a fix.

 

Thanks,

Greg

 

 

From: tiago [mailto:cslanet@lhotka.net]
Sent: Sunday, November 08, 2009 6:58 PM
To: Greg@GregsPad.com
Subject: Re: [CSLA .NET] Using a custom role provider with CSLA 3.6.2

 

RockfordLhotka:

I see what you are saying, and that's an oversight.

I made up this scheme for identifying a static method - there is no standard for this. In retrospect I probably should have forced you to add two elements to appSettings, one to identify the type, the other to identify the method name...

I'll add this to the bug list, but I'm busy so it won't happen soon (and maybe not in the version of CSLA you are using depending on how old it is), so you might want to change the code in ApplicationSettings (or whereever) that parses this value to make it work in the meantime.

Hi Rocky,

Is this issue solved?



RockfordLhotka replied on Sunday, November 08, 2009

This item is still in the backlog.

 

You can fix it yourself btw – there’s just one method that does the parsing of the config string – change that to meet your needs and you are on your way.

GregJ replied on Monday, November 09, 2009

Thanks!

 

Greg

 

 

From: Rockford Lhotka [mailto:cslanet@lhotka.net]
Sent: Sunday, November 08, 2009 10:25 PM
To: Greg@GregsPad.com
Subject: RE: [CSLA .NET] Using a custom role provider with CSLA 3.6.2

 

This item is still in the backlog.

 

You can fix it yourself btw – there’s just one method that does the parsing of the config string – change that to meet your needs and you are on your way.



Copyright (c) Marimer LLC