首页 文章

ASP.NET Core 2.0 LDAP Active Directory身份验证

提问于
浏览
13

我从过去发现了很多信息说LDAP authentication isn't enabled yet but you can get around that using third party packages.但是,似乎LDAP身份验证WAS implemented back in January . 我似乎无法找到任何关于如何实现它的信息 .

我已经在我的项目中设置了custom authentication,我只需要逻辑来填充 HandleAuthenticateAsync 方法 .

我尝试使用other examples,但它们似乎不适用于.NET Core 2.0 .

这是我能想到的唯一相关代码

protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
    // Get Authorization header value
    if (!Request.Headers.TryGetValue(HeaderNames.Authorization, out var authorization)) {
        return Task.FromResult(AuthenticateResult.Fail("Cannot read authorization header."));
    }

    // TODO: Authenticate user

    // Create authenticated user ticket
    var identities = new List<ClaimsIdentity> { new ClaimsIdentity("custom auth type") };
    var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme);

    return Task.FromResult(AuthenticateResult.Success(ticket));

    // else User not authenticated
    return Task.FromResult(AuthenticateResult.Fail("Invalid auth key."));
}

所以,我的问题是,如何在.NET Core 2.0中实现LDAP身份验证?

2 回答

  • 11

    感谢Win的Answer指出我需要使用Windows Compatibility Pack,我能够解决这个问题 .

    我要做的第一件事是安装Nuget package

    Install-Package Microsoft.Windows.Compatibility
    

    那时,我需要一个预览版本,所以我在这个命令的末尾添加了 -Version 2.0.0-preview1-26216-02

    然后,为 System.DirectoryServicesSystem.DirectoryServices.AccountManagement 添加using语句

    然后,只需将此逻辑插入我的 HandleAuthenticateAsync 方法:

    const string LDAP_PATH = "EX://exldap.example.com:5555";
    const string LDAP_DOMAIN = "exldap.example.com:5555";
    
    using (var context = new PrincipalContext(ContextType.Domain, LDAP_DOMAIN, "service_acct_user", "service_acct_pswd")) {
        if (context.ValidateCredentials(username, password)) {
            using (var de = new DirectoryEntry(LDAP_PATH))
            using (var ds = new DirectorySearcher(de)) {
                // other logic to verify user has correct permissions
    
                // User authenticated and authorized
                var identities = new List<ClaimsIdentity> { new ClaimsIdentity("custom auth type") };
                var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme);
                return Task.FromResult(AuthenticateResult.Success(ticket));
            }
        }
    }
    
    // User not authenticated
    return Task.FromResult(AuthenticateResult.Fail("Invalid auth key."));
    
  • 13

    根据#2089,它仅适用于.NET内核的Windows兼容包 . 我目前使用Novell.Directory.Ldap.NETStandard .

    public bool ValidateUser(string domainName, string username, string password)
    {
       string userDn = $"{username}@{domainName}";
       try
       {
          using (var connection = new LdapConnection {SecureSocketLayer = false})
          {
             connection.Connect(domainName, LdapConnection.DEFAULT_PORT);
             connection.Bind(userDn, password);
             if (connection.Bound)
                return true;
          }
       }
       catch (LdapException ex)
       {
          // Log exception
       }
       return false;
    }
    

    对于身份验证和授权,我们可以使用Cookie身份验证中间件和声明 .

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
       ILoggerFactory loggerFactory)
    {
       app.UseCookieAuthentication(new CookieAuthenticationOptions
       {                
          AuthenticationScheme = "AuthenticationScheme",
          LoginPath = new PathString("/Account/Login"),
          AccessDeniedPath = new PathString("/Common/AccessDenied"),
          AutomaticAuthenticate = true,
          AutomaticChallenge = true
       });
    }
    

    它的移动件很少,所以我在GitHub上创建了一个工作示例项目 . 有两个主要部分 - LdapAuthenticationServiceSignInManager .

相关问题