System.Web.Security.RoleProviderを継承するクラスを持つWCFサービスがあります。このクラスでは、役割管理にAuthorization Manager(AzMan)(AzRoles.dllを使用)を使用します。
認証はADAMインスタンスにあります。
負荷がかかっているサービスで問題が発生しており、呼び出しごとにAzManストアが開いたり閉じたりするようにサービスを変更する必要があるようです。そうしないと、オブジェクトが解放されず、最終的にアプリプールがクラッシュします。起こっているようです-私はこれを100%確認することができませんでした。
元のコードでは、AzManストアは次のようにオーバーライドされたInitializeメソッドで初期化されました。
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;
}
}
}
.
.
.
}
このメソッドがいつ正確に呼び出されるかはわかりません。VSで実行してブレークポイントを設定すると、ヒットすることはありません。このクラスは、セクションのweb.configでそのクラスへの参照を設定することによってインスタンス化されます。
多くの調査を行った後、AzManストアを使い捨てクラスでラップする方法を提案するこのブログ投稿に出くわしました-十分に簡単です。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;
}
}
このコードを実行すると、AzManストアのInitializeメソッドが呼び出されたときにFileNotFoundExceptionが発生します。接続文字列が正しいことを確認しました。
特に苛立たしいのは、このコードをVS 2010内でローカルに実行すると機能することですが、展開してWCFサービスとして実行すると、userIDとLDAP接続文字列が同じでも前述のエラーが発生します。
次に、初期化メソッドは、IISアプリプールが実行されているものと同じように実行され、その外部のコードは、許可されていないユーザーとして実行されているのではないかと思いました。そこで、同僚が書いた特別なクラスを使用して、AzManの初期化メソッドを呼び出すときに偽装をオフにしました。ユーザーがネットワークサービスであることを確認しましたが、それでも同じFileNotFoundExceptionが発生します。私はIT担当者と協力してさまざまな権限設定を試してきましたが、これまでのところうまくいきません。
なぜ私がこのエラーを受け取るのかについて誰かが何か考えを持っていますか?どの権限を確認する必要がありますか?
おそらく、AzManを使用するための私のアプローチは間違っています-私のアーキテクチャに欠陥があります(私がAzManを使用しているという事実を除いて?)