【问题标题】:OWIN with LDAP Authentication带有 LDAP 身份验证的 OWIN
【发布时间】:2015-10-23 02:20:50
【问题描述】:

这是我的场景。我有一个使用 Owin 作为身份验证机制的 MVC 5 应用程序。默认模板在登录操作中调用 SignInManager.PasswordSignInAsync,我想覆盖该操作以使用 LDAP 验证用户而不是查看数据库。

我可以通过以下方式进行验证:

PrincipalContext dc = new PrincipalContext(ContextType.Domain, "domain.com", "DC=domain,DC=com", "user_name", "password");
        bool authenticated = dc.ValidateCredentials(userName, password);

然后我可以使用以下方法检索 UserPrincipal:

UserPrincipal user = UserPrincipal.FindByIdentity(dc, IdentityType.SamAccountName, userName);

但是,我被困在这里,我不确定如何继续登录用户。目标是,在我登录用户后,我将有权访问 User.Identity,包括用户所在的所有角色。本质上,应用程序的行为应该像使用 Windows 身份验证一样,但凭据由用户提供登录页面。

您可能会问为什么不直接使用 Windows 身份验证。该应用程序将从网络外部访问,但要求是使用 AD 身份验证和授权。这就是我的困境。

非常感谢任何建议。

谢谢。

【问题讨论】:

    标签: asp.net-mvc-5 ldap owin


    【解决方案1】:

    经过数小时的研究和反复试验,我最终做到了:

    1. AccountController.cs - 创建应用用户并登录

      ApplicationUser usr = new ApplicationUser() { UserName = model.Email }; bool auth = await UserManager.CheckPasswordAsync(usr, model.Password); 如果(授权) { 列表声明 = new List();
                  foreach (var group in Request.LogonUserIdentity.Groups)
                  {
                      string role = new SecurityIdentifier(group.Value).Translate(typeof(NTAccount)).Value;
                      string clean = role.Substring(role.IndexOf("\\") + 1, role.Length - (role.IndexOf("\\") + 1));
                      claims.Add(new Claim(ClaimTypes.Role, clean));
                  }
                  claims.Add(new Claim(ClaimTypes.NameIdentifier, model.Email));
                  claims.Add(new Claim(ClaimTypes.Name, model.Email));
                  ClaimsIdentity ci = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
                   AuthenticationManager.SignIn(new AuthenticationProperties()
                   {
                       AllowRefresh = true,
                       IsPersistent = false,
                       ExpiresUtc = DateTime.UtcNow.AddDays(7),
                   }, ci);
                   return RedirectToLocal(returnUrl);
                  }
                  else
                  {
                      ModelState.AddModelError("", "Invalid login credentials.");
                      return View(model);
                  }
      
    2. IdentityConfig.cs (CheckPasswordAsync) - 针对 LDAP 进行身份验证

      公共覆盖异步任务 CheckPasswordAsync(ApplicationUser 用户,字符串密码) { PrincipalContext dc = new PrincipalContext(ContextType.Domain, "domain", "DC=domain,DC=com", [user_name], [password]); bool 认证 = dc.ValidateCredentials(user.UserName, password); 返回认证; }
    3. Global.asax - 如果您在登录表单中使用防伪令牌

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

    此时,您将登录并可以访问 User.Identity 对象。您还可以使用 [Authorize(Roles = "some_role"]

    标记控制器和操作

    事实证明,这比我想象的要容易,只是关于这个主题的文章并不多(至少我找不到任何东西)。

    此外,此代码假定您正在从可以访问网络上的域控制器的服务器运行应用程序。如果您在 DMZ 服务器上,则需要与您的网络管理员讨论此策略以获取其他选项。

    我希望这可以为您节省一些时间。我也很想听听社区对此的看法。也许有更好的方法来处理这种情况。如果有,请在这里分享。

    谢谢。

    丹尼尔 D.

    【讨论】:

    • 要创建 PrincipalContext 实例,[user_name] 和 [password] 将来自有权查询 LDAP 的帐户?
    • 正确。此帐户必须能够在 LDAP 中查找用户
    • 这太棒了!太感谢了。我花了几个小时在 MVC 中寻找 LDAP 身份验证的最佳选项。你是救生员!谢谢。
    • 很高兴我能帮上忙 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 2015-09-23
    相关资源
    最近更新 更多