问题 如何在Nancy中针对Active Directory进行身份验证?


这是一篇过时的文章,但是 http://msdn.microsoft.com/en-us/library/ff650308.aspx#paght000026_step3 说明我想做什么。我选择了 南希 作为我的网络框架,因为它的简单性和低礼仪的方法。因此,我需要一种方法来使用Active Server进行身份验证 南希

在ASP.NET中,看起来您只需通过web.config文件中的某些设置在基于数据库的成员资格提供程序和Active Directory之间切换即可。我不需要具体,但在开发和生产之间切换的能力将是惊人的。

如何才能做到这一点?


12653
2017-09-12 17:32


起源

顺便说一下,如果现在没有这个,我会做出贡献..任何指导都会有所帮助。 - Byron Sommardahl
我刚刚向南希回购添加了一个问题: github.com/NancyFx/Nancy/issues/742 - Byron Sommardahl


答案:


真的解决方案比看起来简单得多。只需将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.");
        }

    }
}

14
2017-09-28 17:06



轻微的挑剔:而不是 LoggedInUserIds.First(x => x.Key == identifier).Value你不能这样做吗? LoggedInUserIds[identifier]?也 LoggedInUserIds[identifier] = adminUser.Id 在里面 Login 方法。 - Asad Saeeduddin
这可以作为Nuget Nancy.ActiveDirectoryAuthentication包吗? - pashute
@pashute 广告讨论 在Nancy的问题跟踪器(后面链接到这个答案) - Omni