我现在也在做一些非常相似的事情。我为内部和外部用户提供单点登录门户,他们可以使用 AD 帐户或指定的用户/密码组合登录。
我目前如何实现这一目标(请注意,这仍在进行中)是通过以下方式实现的。我也在使用ASP.NET 身份 2.1 阿尔法 http://blogs.msdn.com/b/webdev/archive/2014/06/05/asp-net-identity-2-1-0-alpha1.aspx其中包括 SignInManager(非常酷)。
- 使用可选密码设置用户帐户(必须为非 AD 用户指定)
- 将 UserLogin 关联到 AD 用户的帐户,ProviderKey 等于其 AD 帐户 Sid
- 在登录时我检测是否
Request.LogonUserIdentity
有一个已知帐户。然后使用以下命令检查它们是否有效UserManager.FindAsync
方法。从这里您可以再次挑战他们,为他们提供以已知用户身份直接登录或直接登录的选项(您在此处选择)。
- 然后,我还允许他们通过检测以域\用户名格式输入的用户名,通过标准用户登录表单登录。这允许域用户在从外部或从其他用户计算机进入您的站点时登录。
此过程中的一些代码片段(这些只是帮助您继续前进的一些示例,因为完整的解决方案分布在我的解决方案中)。
使用 Request.LoginUserIdentity 登录。这可能是您帐户控制器中的一种方法。
public async Task<ActionResult> WindowsLogin(string returnUrl)
{
var loginInfo = GetWindowsLoginInfo();
var user = await _userManager.FindAsync(loginInfo);
if (user != null)
{
await SignInAsync(user, false);
return RedirectTo(returnUrl, "Manage");
}
return RedirectToAction("Login");
}
private UserLoginInfo GetWindowsLoginInfo()
{
if (Request.LogonUserIdentity == null || Request.LogonUserIdentity.User == null)
{
return null;
}
return new UserLoginInfo("Windows", Request.LogonUserIdentity.User.ToString());
}
我还在我的 ApplicationSignInManager(继承自 SignInManager)中添加了一个方法,以允许用户使用标准登录表单使用其 AD 详细信息登录。
public async Task<SignInStatus> WindowsLoginAsync(string userName, string password, bool isPersistent)
{
var signInStatus = SignInStatus.Failure;
using (var context = new PrincipalContext(ContextType.Domain, "YourDomain"))
{
// validate the credentials
bool credentialsValid = context.ValidateCredentials(userName, password);
if (credentialsValid)
{
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(context, userName);
if (userPrincipal != null)
{
var loginInfo = new ExternalLoginInfo
{
Login = new UserLoginInfo(AuthenticationTypes.Windows, userPrincipal.Sid.ToString())
};
signInStatus = await ExternalSignInAsync(loginInfo, isPersistent);
}
}
}
return signInStatus;
}
然后可以在您的登录方法中使用它,如下所示。
Regex domainRegex = new Regex("(domain\\.+)|(.+@domain)");
if (domainRegex.IsMatch(model.Username))
{
result = await _signInManager.WindowsLoginAsync(model.Username, model.Password, model.RememberMe);
switch (result)
{
case SignInStatus.Success:
return RedirectTo(returnUrl, "Manage");
}
}
result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, true);
...
我希望其中的一些内容可以帮助您解决问题!