2012-06-08 20 views
4

(這個問題類似於Get UPN or email for logged in user in a .NET web application,但並不完全。)如何使用Windows身份驗證獲得UPN在.NET Web應用程序驗證用戶,沒有查詢Active Directory

在.NET(C#)Web應用程序,我想找到登錄用戶的UPN。

我知道如何通過查詢Active Directory來執行此操作:從HttpContext.Current.User.Identity as WindowsIdentity獲取'DOMAINNAME \ userName';請在ldap://RootDSE下查找DOMAINNAME,並找到其dnsRoot;在ldap://...dnsRoot...下查詢(&(objectCategory=person)(objectClass=user)(sAMAccountName=...userName...));獲取該條目的userPrincipalName屬性。 (更多細節回答https://stackoverflow.com/a/513668/223837)。

我的問題:可以找到UPN 沒有呼叫Active Directory嗎?考慮到微軟在全球各地使用UPN的重點,UPN是否已經存儲在用戶通過Web服務器認證時創建的令牌中?

(支持觀察:如果我在Windows 7上運行whoami /upn,然後Wireshark的不顯示任何Active Directory連接。)

(如果這有什麼差別:請注意,我們的web應用程序不使用模擬,即我們的網絡應用程序不在用戶身份下運行。)

回答

4

嘗試System.DirectoryServices.AccountManagement.UserPrincipal.Current,它具有屬性UserPrincipalName。當然,這需要應用程序在Windows身份驗證下運行。

編輯呃,它看起來像這個API仍然執行目錄查找。

+0

嗯,至少這是一個沒有任何_explicit_ AD查詢,從刪除AD相關的複雜性我們的代碼。但是,我想知道這是否也適用於我們的_non-impersonated_ .NET應用程序:UserPrincipal.Current是否包含Web應用程序的身份或經過身份驗證的用戶身份?不幸的是,文檔建議前者:「獲取表示線程正在運行的當前用戶的用戶主體對象。」 –

+0

是的,它獲取Windows標識,如果您未使用Windows和集成身份驗證或模擬,那將是應用程序池的標識。使用上下文查看收縮者的文檔:它可以讓您填寫所需用戶的詳細信息,然後查詢並加載您的詳細信息。正如您所說的,您可以自己節省您的LDAP查詢的複雜性。 – HackedByChinese

+1

'new UserPrincipal(context,...)'似乎對我沒有幫助,因爲我需要知道用戶的密碼。但是,似乎臨時模仿可能會起作用:'var wi = HttpContext.Current.User.Identity作爲WindowsIdentity;使用(wi.Impersonate()){upn = UserPrincipal.Current.UserPrincipalName; }' 我還是要試試這個。 –

2

我在使用System.DirectoryServices.AccountManagement.UserPrincipal.Current時遇到Active Directory查詢問題,所以我使用GetUserNameExNameUserPrincipal格式。

該函數獲取有關當前用戶的信息,因此如果您尚未使用此功能,則需要假冒。

public enum EXTENDED_NAME_FORMAT 
{ 
    NameUnknown = 0, 
    NameFullyQualifiedDN = 1, 
    NameSamCompatible = 2, 
    NameDisplay = 3, 
    NameUniqueId = 6, 
    NameCanonical = 7, 
    NameUserPrincipal = 8, 
    NameCanonicalEx = 9, 
    NameServicePrincipal = 10, 
    NameDnsDomain = 12 
} 

[DllImport("secur32.dll", CharSet = CharSet.Auto)] 
public static extern int GetUserNameEx(int nameFormat, StringBuilder userName, ref int userNameSize); 

然後調用它像這樣:在C#中可以通過導入功能來完成

string upn = null; 
StringBuilder userName = new StringBuilder(1024); 
int userNameSize = userName.Capacity; 
if (GetUserNameEx((int)EXTENDED_NAME_FORMAT.NameUserPrincipal, userName, ref userNameSize) != 0) 
{ 
    upn = userName.ToString(); 
} 
相關問題