2010年7月21日 星期三

探討ASP.NET Run Account

會寫這篇文章是因為最近使用WCF 呼叫 COM object的時候遇到了權限的問題。原本我一直以為WCF host on IIS的時候,他的Run Account就會和ASP.NET的設定一樣,由於我原本所撰寫呼叫的COM object使用WCF host在IIS上的時候,一直出現奇怪的錯誤(看不出來是權限問題),但是host在console ap or windows service上面都是OK的,所以我還是直覺是Run Account的問題。為了解決這個問題我才知道WCF的Run Account並不是跟ASP.NET的設定一樣,而是直接聽命於Application pool的Run Account。底下做了一些實驗(PS:先確定ASP.NET的authentication mode為windows)。

實驗一:預設的Run Account (新增一個aspx的頁面,並於加入底下程式碼)
protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    }
上面的程式碼執行結果如下
 由上圖可知,預設為NETWORK SERVICE的帳號在執行asp.net的頁面



實驗二: 當使用impersonate時



執行結果如下

由上圖可知,使用impersonate之後的Run Account改為匿名的帳號了,如下
實驗三:WCF的Run Account
請先新增一WCF Service,並撰寫程式碼如下
//制定ServiceContract(IWCFService.cs)
[ServiceContract]
public interface IWCFService
{
    [OperationContract]
    string GetRunAccount();
}

//實做契約
public class WCFService : IWCFService
{
    public string GetRunAccount()
    {
        //回傳Run Account
        return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    }
}

然後請先增Client proxy (這裡就不介紹怎麼新增Client Proxy了),且在aspx中呼叫WCFService,程式碼如下
protected void Page_Load(object sender, EventArgs e)
    {
        //Label1.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
        WCFServiceReference.WCFServiceClient client = 
            new WCFServiceReference.WCFServiceClient();
        Label1.Text = client.GetRunAccount();

        client.Close();
    }

期執行結果如下
注意,這裡出現的Run Account確實讓我感到非常意外,我原本以為應該是與實驗二的結果一樣才是,經過google大神的指導,我才知道這裡的Run Account是follow Application pool的,如下
 所以當我們在這裡修改程式集區的執行帳戶時
 執行的結果如下

確實是聽從Application Pool的執行帳號

結論:
沒寫過不知道,寫了之後就知道。這種地方一般的WCF書籍並不會寫到,而且可能也不會有很多機會Host on IIS的時候需要調整執行帳戶的。但事情就是這麼巧,就這樣讓我碰到了,這個問題我花了兩天才找出來,從呼叫COM object開始追,最後追到這裡才追到。另外,其實在impersonate的時候,也可以指定其他帳戶,但這個其他帳戶都是屬於ASP.NET的,對WCF並不會起作用喔。








沒有留言: