12

我正在使用MVC 4 Intranet應用程序並使用Windows身份驗證。我想向用戶對象添加身份驗證方法使用(@User)並從活動目錄(例如電子郵件,電話號碼等)獲取該數據。在MVC中使用Windows身份驗證獲取Active Directory用戶信息4

我知道我可以創建自定義屬性授權並將其添加到我的所有其他控制器繼承控制器,但我不知道這是做我想做什麼是正確的方法。

我的最終目標很簡單,我想@user對象爲具有在通過Active Directory填充其他屬性。謝謝你盡你所能的幫助。

回答

28

我正要加入我自己的問題與我的解決方案,計算器,幫助他人這個問題,當我看到你的存在的問題。看起來這將是一件非常普遍的事情,但是關於如何做到這一點的信息只是分散在多個來源之間,很難追蹤。不只有一個完整的資源,所以希望這可以幫助你和其他人。

這樣做的最好方法是使用UserPrincipal擴展。基本上,您從System.DirectoryServices.AccountManagement繼承UserPrincipal並添加您自己的附加屬性。這是通過ExtensionGetExtensionSet(有些神奇的)方法啓用的。

[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] 
public class UserPrincipalExtended : UserPrincipal 
{ 
    public UserPrincipalExtended(PrincipalContext context) : base(context) 
    { 
    } 

    public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) 
     : base(context, samAccountName, password, enabled) 
    { 
    } 

    [DirectoryProperty("title")] 
    public string Title 
    { 
     get 
     { 
      if (ExtensionGet("title").Length != 1) 
       return null; 

      return (string)ExtensionGet("title")[0]; 
     } 

     set 
     { 
      ExtensionSet("title", value); 
     } 
    } 

    [DirectoryProperty("department")] 
    public string Department 
    { 
     get 
     { 
      if (ExtensionGet("department").Length != 1) 
       return null; 

      return (string)ExtensionGet("department")[0]; 
     } 

     set 
     { 
      ExtensionSet("department", value); 
     } 
    } 

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue) 
    { 
     return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue); 
    } 

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue) 
    { 
     return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue); 
    } 
} 

該類的兩個屬性需要定製到您的AD實例。 DirectoryRdnPrefix的值需要是AD中的RDN(相對可分辨名稱),而DirectoryObjectClass的值需要是AD中用於userObject類的目錄對象類型名稱。對於典型的AD域服務設置,它們應該與上面提供的代碼一樣,但對於LDS設置,它們可能不同。我已經添加了兩個我的組織使用的新屬性,「標題」和「部門」。從中,您可以瞭解如何添加任何其他您喜歡的屬性:基本上,您只需使用我在此處提供的模板創建屬性。該屬性可以任意命名,但傳遞給DirectoryProperty的字符串值在代碼塊內應與AD的屬性名稱匹配。有了這個,您可以使用PrincipalContext與您的子類而不是UserPrincipal來獲取具有您需要添加的屬性的用戶對象。

UserPrincipalExtended user = UserPrincipalExtended.FindByIdentity(
    new PrincipalContext(ContextType.Domain), User.Identity.Name); 

和訪問你的財產像任何其他的UserPrincipal實例:

// User's title 
user.Title 

如果你不熟悉System.DirectoryServices.AccountManagement.UserPrincipal,有一個在烤幾個用戶屬性:GivenNameSurnameDisplayName等。特別是針對你的情況,由於你特意提到了電話和電子郵件,因此有VoiceTelephoneNumberEmailAddress。您可以在MSDN docs中看到完整列表。如果您所需要的只是內置信息,則不需要按照上面所示擴展UserPrincipal。你會只是做:

UserPrincipal user = UserPrincipal.FindByIdentity(
    new PrincipalContext(ContextType.Domain), User.Identity.Name); 

但是,9次了10年的內置插件是不夠的,所以它的好,知道如何輕鬆獲得休息。

最後,我不希望將@using行添加到任何使用此視圖的視圖中,因此我繼續將名稱空間添加到我的Views文件夾的web.config中。該部分很重要,需要將其添加到Views文件夾的web.config中,而不是項目(如果您正在使用區域,則需要將每個區域的Views文件夾添加到該文件夾​​中)。

<system.web.webPages.razor> 
    ... 
    <pages pageBaseType="System.Web.Mvc.WebViewPage"> 
     <namespaces> 
      ... 
      <add namespace="System.DirectoryServices.AccountManagement" /> 
      <add namespace="Namespace.For.Your.Extension" /> 
     </namespaces> 
    </pages> 
</system.web.webPages.razor> 
+0

,但我沒有與userprincipal類的經驗。我用這個新類替換了我的UserPrincipal類型,但在調用靜態FindByIdentity方法時出錯。其他信息:UserPrincipalExtended類型的主對象不能用於對該商店的查詢。任何想法爲什麼它失敗? –

-1
[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] 

這些都沒有得到認可。你剛剛在你的mvc 4剃鬚刀項目中創建了一個控制器嗎?

我不能如找個或添加我喜歡這個擴展的參考System.DirectoryServices.AccountManagement

相關問題