2011-01-20 65 views
1

我有一个WCF服务,它有一个继承System.Web.Security.RoleProvider的类。在这个类中,我使用授权管理器(AzMan) - 使用AzRoles.dll进行角色管理。调用AzMan对象的初始化方法会导致FileNotFoundException

身份验证在ADAM实例中。

我一直在加载服务时遇到问题,好像我需要更改服务,以便AzMan商店每次调用都打开并关闭 - 否则对象不会被释放,最终应用程序池会崩溃 - 至少这似乎正在发生 - 我一直无法证实这100%。

在原来代码中的商店AzMan的在重写的初始化方法初始化这样的:

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的初始化方法被调用FileNotFoundException异常。我已确认连接字符串是正确的。

什么是特别令人沮丧的是,如果我在VS 2010本地运行它,但如果我部署它并作为WCF服务运行它,我会得到我提到的错误事件,尽管userID和LDAP连接字符串是相同的。

我读这blog post and posted article

我当时想,也许因为无论IIS应用程序池的运行初始化方法正在运行,那外面的代码运行的imperonated用户。所以,使用一个同志写的特殊类,我在调用AzMan intialize方法时关闭了模拟。我确认用户是网络服务,但我仍然得到相同的FileNotFoundException。我一直在与IT人员合作尝试不同的权限设置,但目前为止还没有运气。

有没有人有任何想法,为什么我得到这个错误?我应该看什么权限?

也许我的方法使用是AzMan的错误 - 是我的架构存在缺陷

回答

1

我想通了,我的问题(除了这个事实,我使用AzMan的?)。我的WCF服务托管在IIS中。 web.config文件中有一个标签。模拟是针对服务运行的服务帐户。当在IIS中托管WCF服务时,ASP.NET将用于启动服务,但就是这样。所以,当应用程序启动时,AzManProvider类被ASP初始化,因此模拟正在完成。 Initialize方法在类实例化时调用。 servcice帐户有权打开AzMan。对WCF服务的调用不使用web.config中的任何ASP condifuration设置。因此,服务调用以应用程序池 - NETWORK SERVICE的身份运行。为了解决这个问题,我们将应用程序池标识更改为服务帐户 - 并从web.config中删除标签。现在,一切正常。

我不明白为什么没有安全权限会抛出FileNotFound异常。

相关问题