【问题标题】:How can I authenticate against Active Directory in Nancy?如何在 Nancy 中针对 Active Directory 进行身份验证?
【发布时间】:2012-09-05 18:54:33
【问题描述】:

这是一篇过时的文章,但http://msdn.microsoft.com/en-us/library/ff650308.aspx#paght000026_step3 说明了我想要做什么。我选择Nancy 作为我的Web 框架,因为它简单且不那么正式。所以,我需要一种使用Nancy 对Active Directory 进行身份验证的方法。

在 ASP.NET 中,您似乎可以通过 web.config 文件中的一些设置在基于 db 的成员资格提供程序和 Active Directory 之间切换。我并不特别需要那个,但是在开发和生产之间切换的能力会很棒。

如何做到这一点?

【问题讨论】:

  • 顺便说一句,如果现在不可用,我会贡献它.. 任何关于该方向的指导也会有所帮助。
  • 我刚刚在 Nancy 仓库中添加了一个问题:github.com/NancyFx/Nancy/issues/742

标签: c# active-directory forms-authentication nancy


【解决方案1】:

确实,解决方案比看起来要简单得多。只需将 Active Directory 视为用户的存储库(就像数据库一样)。您需要做的就是查询 AD 以验证输入的用户名和密码是否有效。所以,只需使用 Nancy 的表单验证并在您的 IUserMapper 实现中处理与 AD 的连接。这是我为我的用户映射器想出的:

public class ActiveDirectoryUserMapper : IUserMapper, IUserLoginManager
{
    static readonly Dictionary<Guid, long> LoggedInUserIds = new Dictionary<Guid, long>(); 

    readonly IAdminUserValidator _adminUserValidator;
    readonly IAdminUserFetcher _adminUserFetcher;
    readonly ISessionContainer _sessionContainer;

    public ActiveDirectoryUserMapper(IAdminUserValidator adminUserValidator, IAdminUserFetcher adminUserFetcher, ISessionContainer sessionContainer)
    {
        _adminUserValidator = adminUserValidator;
        _adminUserFetcher = adminUserFetcher;
        _sessionContainer = sessionContainer;
    }

    public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
    {
        _sessionContainer.OpenSession();
        var adminUserId = LoggedInUserIds.First(x => x.Key == identifier).Value;
        var adminUser = _adminUserFetcher.GetAdminUser(adminUserId);
        return new ApiUserIdentity(adminUser);
    }

    public Guid Login(string username, string clearTextPassword, string domain)
    {
        var adminUser = _adminUserValidator.ValidateAndReturnAdminUser(username, clearTextPassword, domain);
        var identifier = Guid.NewGuid();
        LoggedInUserIds.Add(identifier, adminUser.Id);
        return identifier;
    }
}

我在我的数据库中保存了一个记录来处理角色,所以这个类处理使用 AD 进行验证并从数据库中获取用户:

public class AdminUserValidator : IAdminUserValidator
{
    readonly IActiveDirectoryUserValidator _activeDirectoryUserValidator;
    readonly IAdminUserFetcher _adminUserFetcher;

    public AdminUserValidator(IAdminUserFetcher adminUserFetcher,
                              IActiveDirectoryUserValidator activeDirectoryUserValidator)
    {
        _adminUserFetcher = adminUserFetcher;
        _activeDirectoryUserValidator = activeDirectoryUserValidator;
    }

    #region IAdminUserValidator Members

    public AdminUser ValidateAndReturnAdminUser(string username, string clearTextPassword, string domain)
    {
        _activeDirectoryUserValidator.Validate(username, clearTextPassword, domain);

        return _adminUserFetcher.GetAdminUser(1);            
    }

    #endregion
}

并且这个类实际上验证了用户名/密码组合是否存在于 Active Directory 中:

public class ActiveDirectoryUserValidator : IActiveDirectoryUserValidator
{
    public void Validate(string username, string clearTextPassword, string domain)
    {
        using (var principalContext = new PrincipalContext(ContextType.Domain, domain))
        {
            // validate the credentials
            bool isValid = principalContext.ValidateCredentials(username, clearTextPassword);
            if (!isValid)
                throw new Exception("Invalid username or password.");
        }

    }
}

【讨论】:

  • 轻微的挑剔:而不是LoggedInUserIds.First(x =&gt; x.Key == identifier).Value,你不能只做LoggedInUserIds[identifier]吗?还有LoggedInUserIds[identifier] = adminUser.IdLogin 方法中。
  • 这可以做成 Nuget Nancy.ActiveDirectoryAuthentication 包吗?
  • @pashute AD discussion 在 Nancy 的问题跟踪器(返回链接到此答案)
最近更新 更多