Friday, November 20, 2009 - 文章

CODE-C#變身術懶人包

以前老覺得,用C#寫身份切換(用不同身份存取資源)程式得借重API,有一堆細節要處理,麻煩得很。

這回發了狠,一口氣把複雜工作通通裝在一個Class裡,呼叫時只要傳入帳號、密碼和網域,取回WindowsImpersonationContext,一切搞定。

就叫它【C#變身術懶人包】吧!

//REF: http://support.microsoft.com/kb/319615
public class ImpersonateHelper
{
    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool LogonUser(string lpszUsername, 
        string lpszDomain, string lpszPassword, int dwLogonType, 
        int dwLogonProvider, ref IntPtr phToken);
 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, 
        SetLastError = true)]
    private static extern bool CloseHandle(IntPtr handle);
 
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, 
        SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr existingTokenHandle, 
        int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle);
 
    // logon types
    const int LOGON32_LOGON_INTERACTIVE = 2;
    const int LOGON32_LOGON_NETWORK = 3;
    const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
 
    // logon providers
    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_PROVIDER_WINNT50 = 3;
    const int LOGON32_PROVIDER_WINNT40 = 2;
    const int LOGON32_PROVIDER_WINNT35 = 1;
 
    public static IntPtr GetDupToken(string userName, string password, 
        string domain)
    {
        IntPtr token = IntPtr.Zero;
        IntPtr dupToken = IntPtr.Zero;
        bool isSuccess = LogonUser(
                            userName,
                            domain,
                            password,
                            LOGON32_LOGON_NEW_CREDENTIALS,
                            LOGON32_PROVIDER_DEFAULT,
                            ref token);
        if (!isSuccess)
            throw new ApplicationException(
                "Failed to LogonUser, Code = " + 
                Marshal.GetLastWin32Error());
        isSuccess = DuplicateToken(token, 2, ref dupToken);
        if (!isSuccess)
            throw new ApplicationException(
                "Failed to DuplicateToken, Code = " + 
                Marshal.GetLastWin32Error());
        return dupToken;
    }
 
    public static WindowsImpersonationContext 
        GetImpersonationContext(
        string userName, string password, string domainName)
    {
        return new WindowsIdentity(
    ImpersonateHelper.GetDupToken(userName, password, domainName)
            ).Impersonate();
    }
 
}
static void test()
{
    Dictionary<string, string> latestList = new Dictionary<string, string>();
    using (WindowsImpersonationContext wic =
        ImpersonateHelper.GetImpersonationContext("username", "pwd",
        "domainOrRemoteServerIp"))
    {
        foreach (string f in
            Directory.GetFiles(@"\\remoteServer\Folder", "*.txt"))
            Console.WriteLine(f);
        wic.Undo();
    }
}
2009第五屆華文部落格大獎初選入圍

俗話說得好,入圍就是得獎!

所以... 我得獎了!! XD

前些時候看到噗浪上有人提到今年度的全球華文部落格大獎開始報名,雖然覺得像本站這種拿技術當主軸的硬綁綁技術部落格,離大眾市場有段距離,得獎希望渺茫。但你也知道,搞技術搞久了,腦袋磨損,就會產生一些偏差行為。例如: 什麼都要量化,凡事都要建立度量的指標、把日常生活也當成系統Tuning... 而網站上也掛滿了Hit Counter、RSS訂閱人數、funP推文計數、部落格觀察排名。

聽到有部落格比賽,不管自己的Blog離雅俗共賞還有多遠的距離,也暫時忘卻網站的人氣其實都靠離題的鬼扯文撐場,反正不用繳報名費(咳... 這是重點),參加就是了,到時拿個成績來參考也好。(好想呼籲大會公布所有評分細節,不過應該沒人理我)

昨個兒初審入圍名單出爐,我參賽的訊息觀點類共158人參加,初審取58人,錄取率為36.70886%。(謎之聲: 怎麼又算起數字來,你無藥可救了)

PS: 最近工作頗為吃緊,部落格人數悄悄地破了110萬也無心發文留念,索性未來就改為20萬再刻一度好了。

搜尋

Go

<November 2009>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication