使用OWIN进行混合模式身份验证



我正在构建一个MVC 5应用程序。我需要根据AD和sql数据库或web服务对人员进行身份验证。

要求是,如果一个人登录到公司网络或通过VPN连接,我必须在不要求凭据的情况下登录他们。如果用户通过互联网访问网站,或者某人没有AD帐户,我必须使用表单身份验证。

我正在看这篇文章,但这将与ASP一起工作。Net MVC和OWIN?还有其他选择吗?

提前谢谢。

我现在也在做类似的事情。我为内部和外部用户提供了一个单一登录门户,他们可以使用AD帐户或指定的用户/密码组合登录。

我目前是如何做到这一点的(请注意,这仍然是一项正在进行的工作)是通过以下方式实现的。我也在使用ASP。NET Identity 2.1 alpha,其中包括SignInManager(非常酷)。

  1. 使用可选密码设置用户帐户(必须为非AD用户指定)
  2. 将UserLogin与AD用户的帐户关联,ProviderKey等于其AD帐户Sid
  3. 在登录时,我检测Request.LogonUserIdentity是否有已知帐户。然后使用UserManager.FindAsync方法检查它们是否为有效用途。从这里,您可以再次挑战他们,为他们提供以已知用户身份直接登录或直接登录的选项(您可以在此处选择)
  4. 然后,我还允许他们通过检测以域\用户名格式输入的用户名,通过标准用户登录表单登录。这允许域用户在外部或从其他用户计算机进入您的网站时登录

这个过程中的一些代码片段(这些只是一些示例,因为完整的解决方案分布在我的解决方案中)。

使用请求登录。登录用户标识。这可能是您的帐户控制器中的一种方法。

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);
...

我希望这些能帮你解决问题!

owin的工作方式是,每个请求都会通过启动时注册的所有中间件模块。

这意味着,如果您希望有多种方式进行身份验证,则需要使用/创建和注册所需的所有不同中间件。然后,每个中间软件将根据各种用户存储进行身份验证,并创建一个ClaimsPrincipal(或多个)。

一个简单的例子,(面向api)看起来是这样的。OAuthBearer是Identity 2.0中的令牌身份验证,BasicAuthentication只是标头中的基本用户/pwd。

//This will create the usermanager per request.
app.CreatePerOwinContext(ApplicationSession.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Token Authentication
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
// Basic Authentication.
app.UseBasicAuthentication(app.CreateLogger<BasicAuthenticationMiddleware>(), 
"Realm", ValidateUser);

祝好运

最新更新