我有一个WCF服务,它有一个继承System.Web.Security.RoleProvider的类。在本课程中,我使用授权管理器(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中设置对它的引用来实例化。
经过大量的研究后,我发现了这个blog post,它提出了一种将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连接字符串是相同的。
我读了这个blog post and posted article
然后我认为初始化方法可能正在运行,因为IIS App池正在运行,并且其外部的代码作为未经授权的用户运行。因此,使用同事写的一个特殊类,我在调用AzMan初始化方法时关闭了模拟。我确认用户是NETWORK SERVICE但我仍然得到相同的FileNotFoundException。我一直在与IT人员一起尝试不同的权限设置,但到目前为止还没有运气。
有没有人知道我为什么会收到这个错误?我应该看什么权限?
也许我使用AzMan的方法是错误的 - 我的架构是否有缺陷(除了我使用AzMan的事实?)
答案 0 :(得分:1)
我发现了我的问题。我的WCF服务托管在IIS中。 web.config文件中有一个标记。模拟是服务帐户运行的服务帐户。当在IIS中托管WCF服务时,ASP.NET用于启动服务,但就是这样。因此,当应用程序启动时,AzManProvider类由ASP初始化,因此模拟正在进行中。在实例化类时调用Initialize方法。 servcice帐户有权打开AzMan。对WCF服务的调用不使用web.config中的任何ASP配置设置。因此,服务调用在应用程序池的标识下运行 - NETWORK SERVICE。为了解决这个问题,我们更改了应用程序池标识以作为服务帐户运行 - 并从web.config中删除了标记。现在,一切正常。
我不明白为什么没有安全权限会抛出FileNotFound异常。