asp.net-mvc-4 - 在 MVC 4 中使用 Windows 身份验证获取 Active Directory 用户信息

标签 asp.net-mvc-4 authentication active-directory windows-authentication

我正在开发 MVC 4 Intranet 应用程序并使用 Windows 身份验证。我想添加到身份验证方法使用的用户对象(@User)并从事件目录中获取该数据(例如电子邮件、电话号码等)。

我知道我可以创建一个自定义授权属性并将其添加到我所有其他 Controller 继承自的 Controller 中,但我不知道这是否是执行我想要的操作的正确方法。

我的最终目标很简单,我希望 @User 对象具有通过 Active Directory 填充的其他属性。感谢您提供的任何帮助。

最佳答案

当我看到您现有的问题时,我正准备将我自己的问题及其解决方案添加到 StackOverflow 中以帮助其他人解决此问题。这似乎是一件很常见的事情,但有关如何做到这一点的信息却分散在多个来源之间,很难追踪。完整的资源不只是一种,因此希望这会对您和其他人有所帮助。

执行此操作的最佳方法是使用 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);

但是,十有八九,内置功能还不够,所以最好知道如何轻松获得其余功能。

最后,我不想向使用此功能的任何 View 添加 @using 行,因此我继续将命名空间添加到我的 Views 文件夹中网络配置。该部分很重要,需要将其添加到 Views 文件夹的 web.config,而不是项目的(以及每个区域的单独 Views 文件夹,如果您正在使用 Areas)。

<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>

关于asp.net-mvc-4 - 在 MVC 4 中使用 Windows 身份验证获取 Active Directory 用户信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20156913/

相关文章:

c# - 如何使用 AuthType.Kerberos 对 Active Directory 中的用户进行身份验证?

asp.net-mvc - 如何从数据库检索 VarBinary 图像到 MVC View

asp.net-mvc-4 - 为什么将 FormsAuthenticationTicket 与 Windows 身份验证结合使用?

rest - 保护 Smooch Webhook 的安全

python - 始终将用户包含在 django 模板上下文中

delphi - 如何将Delphi 与Active Directory 集成?

c# - razor View 引擎中的全局函数

c# - 在 ASP.NET MVC 中,当 Model.isvalid 为 false 时如何将验证消息重定向并显示回局部 View

windows - 使用支持 NFC 的手机解锁计算机

powershell - 为什么新 AD 用户不复制组成员身份?