Asp.net-Mvc-4

在 MVC 4 中使用 Windows 身份驗證獲取 Active Directory 使用者資訊

  • May 30, 2017

我正在開發 MVC 4 Intranet 應用程序並使用 Windows 身份驗證。我想添加到身份驗證方法使用的使用者對象(@User)並從活動目錄(例如電子郵件、電話號碼等)中獲取該數據。

我知道我可以創建一個自定義 Authorize 屬性並將其添加到我所有其他控制器都繼承自的控制器中,但我不知道這是否是做我想做的正確方法。

我的最終目標很簡單,我希望 @User 對象具有通過 Active Directory 填充的其他屬性。謝謝你的盡心幫助。

當我看到您現有的問題時,我正準備用我的解決方案將我自己的問題添加到 StackOverflow 以幫助其他人解決這個問題。看起來這將是一件非常普遍的事情,但是有關如何執行此操作的資訊僅分佈在多個來源之間並且難以追踪。不只是一個完整的資源,所以希望這會對​​您和其他人有所幫助。

最好的方法是使用 UserPrincipal 擴展。基本上,您是UserPrincipal從子類化System.DirectoryServices.AccountManagement並添加您自己的附加屬性。這是通過ExtensionGetand ExtensionSet(有點神奇)方法啟用的。

[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 實例進行定制。for 的值DirectoryRdnPrefix需要是 AD 中的 RDN(相對專有名稱),而 for 的值DirectoryObjectClass需要是 AD 中 userObject 類的目錄對像類型名稱。對於典型的 AD 域服務設置,它們都應該與上述程式碼中使用的一樣,但對於 LDS 設置,它們可能會有所不同。我添加了我的組織使用的兩個新屬性,“title”和“department”。由此,您可以了解如何添加您喜歡的任何其他屬性:基本上您只需使用我在此處提供的模板創建一個屬性。該屬性可以命名為任何您喜歡的名稱,但傳遞給的字元串值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 文件中查看完整列表。如果您只需要內置資訊,則不需要UserPrincipal像我上面顯示的那樣進行擴展。你會這樣做:

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

但是,十分之九,內置外掛是不夠的,所以知道如何輕鬆獲得其餘部分是件好事。

最後,我不想在@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>

引用自:https://stackoverflow.com/questions/20156913