Asp.net-Mvc-5

帶有 LDAP 身份驗證的 OWIN

  • October 22, 2015

這是我的場景。我有一個使用 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 身份驗證和授權。因此我的困境。

任何建議都受到高度讚賞。

謝謝你。

經過數小時的研究和反複試驗,這就是我最終要做的事情:

  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);
       }
  1. 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);
返回認證;
}
  1. Global.asax - 如果您在登錄表單中使用防偽令牌
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

此時,您將登錄並可以訪問 User.Identity 對象。您還可以使用標記控制器和操作

$$ Authorize(Roles = “some_role” $$ 事實證明,這比我想像的要容易,只是關於這個主題的真正寫得不多(至少我找不到任何東西)。

此外,此程式碼假定您正在從可以訪問網路上的域控制器的伺服器執行應用程序。如果您在 DMZ 伺服器上,則需要與您的網路管理員討論此策略以獲取其他選項。

我希望這可以為您節省一些時間。我也很想听聽社區對此的看法。也許有更好的方法來處理這種情況。如果是這樣,請在這里分享。

謝謝。

丹尼爾·D。

引用自:https://stackoverflow.com/questions/33180687