I have A WCF service that has a class that inherits System.Web.Security.RoleProvider. In this class I use Authorization Manager (AzMan) - using AzRoles.dll - for role management.
Authentication is in an ADAM instance.
I have been having trouble with my service under load and it seemed like I need to change the service so that the AzMan store was opened and closed for each call - otherwise objects were not being released and eventually the app pool would crash - at least that is what seems to be going on - I have been unable to confirm this 100%.
In the original code the AzMan store was initialized in the overridden Initialize method like this:
public class AzManProvider : RoleProvider {
.
.
.
public override void Initialize( string name, System.Collections.Specialized.NameValueCollection config ) {
base.Initialize( name, config );
if ( config != null ) {
string appName = null;
string connStr = null;
foreach ( string k in config.Keys ) {
string key = k.ToLower().Trim();
string value = config[k];
if ( key == "applicationName".ToLower() ) {
appName = value;
} else if ( key == "connectionStringName".ToLower() ) {
connStr = ConfigurationManager.ConnectionStrings[value].ConnectionString;
}
}
if ( connStr.IsEmpty() )
throw new ArgumentNullException( "connectionStringName" );
CurrentApplicationName = appName;
m_azManStore = new AzAuthorizationStoreClass();
try {
m_azManStore.Initialize( 0, connStr, null );
} catch ( Exception ex ) {
throw ex;
}
}
}
.
.
.
}
I am not sure when this method is called exactly. If you run it in VS and put a break point, it will never hit. This class is instantiated by setting a reference to it in the web.config in the section.
After doing a lot of research I came across this blog post that suggested a way to wrap the AzMan store in a disposable class - easy enough. I created a class that implements IDisposable:
public class AzManHelper : IDisposable
{
public IAzAuthorizationStore Store { get; private set; }
public IAzApplication Application { get; private set; }
public AzManHelper(string appName)
{
string connStr = ConfigurationManager.ConnectionStrings["AzMan"].ConnectionString;
try
{
this.Store = new AzAuthorizationStoreClass();
this.Store.Initialize(0, connStr, null); //<-- Exception occurs here
this.Store.UpdateCache(null);
if (!String.IsNullOrEmpty(appName))
this.Application = this.Store.OpenApplication(appName, null);
}
catch (COMException cex)
{
HandleCOMException(cex);
}
}
public void Dispose()
{
if (this.Application == null)
return;
Marshal.FinalReleaseComObject(this.Application);
if(this.Store != null)
Marshal.FinalReleaseComObject(this.Store);
this.Application = null;
this.Store = null;
}
}
Now, when I run this code I get a FileNotFoundException when the Initialize method on the AzMan store is called. I have confirmed that the connection string is correct.
What is especially frustrating is that this code will work if i run it locally within VS 2010 but if I deploy it and run it as a WCF service I get the error I mentioned eventhough the userID and LDAP connect string are the same.
I read this blog post and posted article
I then thought that maybe the initialize method is being run as whatever the IIS App pool is running as and the code outside of that is run as the imperonated user. So, using a special class that a collegue wrote, I turned off impersonation when calling the AzMan intialize method. I confirmed that the user was NETWORK SERVICE but I STILL get the same FileNotFoundException. I have been working with out IT guys to try different permission settings but so far no luck.
Does anybody have any idea as to why I am getting this error? What permissions should I be looking at?
Perhaps my approach to using AzMan is wrong - is my architecture flawed (besides the fact that I am using AzMan?)