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();
    }
}
歡迎推文分享:
Published 20 November 2009 01:55 PM 由 Jeffrey
Filed under:
Views: 15,308



意見

# alimalik199@gmail.com said on 20 November, 2009 03:36 AM

Linux Web Hosting For Small Businesses.

http://twurl.nl/1ri4oo

# 過路客 said on 24 November, 2009 10:56 PM

domainOrRemoveServerIp=DomainOrRemoteServerIP ?

# Jeffrey said on 25 November, 2009 02:47 AM

to 過路客, 謝謝指正,打錯字了

# Xman said on 30 November, 2009 03:30 AM

請問版大,您是否有使用Case tool記錄開發系統的相關文件?

如果有的話,是用那種工具呢?謝謝。

# Jeffrey said on 02 December, 2009 08:34 AM

to Xman, 其實我不算軟體工程方法論的信徒(還有點像叛徒),純粹是愛Coding而已, 說明文件不講究格式規範,以清楚陳述為主(跟寫Blog一樣爾偶還不忘搞笑),工作上的文件只用VSS保留改版歷程而已。但我的程式碼註解量蠻多的,積陰德順便拯救自己的健忘。

# Dogg04 said on 27 September, 2010 04:23 AM

請問為什麼我沒辦法使用

(WindowsImpersonationContext wic = ImpersonateHelper.GetImpersonationContext("administrator", "easyuse", "192.168.66.128")

登入呢??

會出現"語彙基元不可以為零" ...是我哪邊參數給錯了嗎?

# Dogg04 said on 27 September, 2010 04:27 AM

版大..剛剛的問題解決了...但是還有另一個問題~~

為什麼我就算密碼或是登入帳號亂輸入~~"isSuccess" 參數仍然是 "true" 呢??

# Kim said on 02 November, 2010 12:21 AM

Dear 黑大

剛測試程式碼,若是要存取跨網域,要使用下面的設定

LOGON32_LOGON_INTERACTIVE

環境只能Run在xp,2003...

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<November 2009>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

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

文章典藏
其他功能

這個部落格


Syndication