I am building an MVC 5 application. I need to authenticate people against an AD and a sql data base or a web service.
Requirement is if a person is logged into corporate network or conneted over VPN i have to log them without asking for credentials. if the users are accessing the web site over internet or a person do not have AD account i have to use forms authentication.
I am looking at this article but will this work with ASP.Net MVC and OWIN? Any other alternative?
Thanks in advance.
I'm doing something very similar at the moment too. I'm providing a single sign-on portal for internal and external users where they can log in with their AD account or a specified user/password combination.
How I'm currently achieving this (note this is still a work in progress) is in the following way. I'm also using the ASP.NET Identity 2.1 alpha that includes the SignInManager (very cool).
Request.LogonUserIdentity
has an known account. Then check if they are a valid use by using the UserManager.FindAsync
method. From here you can challenge them again, provide them with an option to log directly in as the known user or log them straight in (your choice here).Some code snippets from this process (these are just some samples to get you going as the complete solution is spread over my solution).
Log in a using the Request.LoginUserIdentity. This could be a method in your account controller.
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());
}
I have also added a method to my ApplicationSignInManager (inherits from SignInManager) to allow a user to log in with their AD details using the standard login form.
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;
}
Then this can be used in your Login method like this.
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);
...
I hope some of this helps you solve the problem!
The way owin works is that every requests drops through all the middleware modules registered in startup.
That means if you want to have multiple ways to authenticate, you would need to use/create and register all the different middleware required. Each middle ware would then authenticate against the various user stores and a ClaimsPrincipal (or many) would be created.
A simple example, (geared towards api) would look like this. The OAuthBearer is token authentication from Identity 2.0 and BasicAuthenication is just that basic user/pwd in the header.
//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);
Good luck
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With