I have an application where I want to to use active directory with individual authentication From Identity in an MVC Application. The idea is I want that each user can sign in with a Form with AD credentials. And manage Roles and permissions with Identity. I'm trying with Owin and now I can authenticate with AD. but I can't assign roles or claims to users, because I don't have them in my database. How can I combine Authentication with AD and Roles and claims from Individual authentication? I used this tuto for AD authentication. http://tech.trailmax.info/2016/03/using-owin-and-active-directory-to-authenticate-users-in-asp-net-mvc-5-application/
1 Answer
Understand this post is old; but, wanted to share what I did to get this to work. Basic idea is to authenticate with AD. Then replicate the credentials in Identity and apply existing Identity roles to the new login. Understand though, this will cause issues if the system requires AD passwords to be changed. The AD's passwords will not update Identity's with this code.
Other things to consider would be to use AD's groups and roles instead of Identity's.
I started with an application that implemented OWIN and Identity 2.0. I then followed the tutorial you have referenced above to add AD authentication. Since I started with Identity and OWIN, all the login code was in place.
- I referenced System.DirectoryServices.AccountManagement
- Created his AdAuthenticationService class
Code for LoginController for me exists in the AccountController. I put the following code in the public async Task Login(LoginViewModel model, string returnUrl) right after the model is validated and before the Identity authentication code. Notice that I removed the return within his code block. I want it to go on to validate by Identity if AD authentication works. If not, it will list all the 'errors' when it returns to the login view.
var authenticationManager = HttpContext.GetOwinContext().Authentication; var authService = new AdAuthenticationService(authenticationManager); var authenticationResult = authService.SignIn(model.UserName, model.Password); if (authenticationResult.IsSuccess) { ModelState.AddModelError("", "AD Authenticated: " + model.UserName); // we are in // check to see if user exixts in AspNetUsers. If not, add with default role. var inAsp = UserManager.Users.Any(x => x.UserName == model.UserName); if (!inAsp) { ModelState.AddModelError("", "Did not find User: " + model.UserName); var newUser = new ApplicationUser { UserName = model.UserName, Email = model.UserName + "@a_company.com" }; ModelState.AddModelError("", "Set new user " + model.UserName); // Add the AD user as an Identity user so we can relate a role to AD Login. var chkUser = UserManager.Create(newUser, model.Password); ModelState.AddModelError("", "Created new user: " + model.UserName + " Error: " + string.Join("\n", chkUser.Errors.ToArray())); //Add default User to Role Admin if (chkUser.Succeeded) { ModelState.AddModelError("", "Created Identity user: " + newUser.UserName); var result1 = UserManager.AddToRole(newUser.Id, "PM"); if (result1.Succeeded) ModelState.AddModelError("","Added PM role to user: " + newUser.UserName); } } }
Pitfalls were:
- Not having the password validation in the IdentityConfig.cs file matching AD's password validation criteria.
- Not having my AppPool's Identity set to LocalSystem.
The shared views, _LoginPartial.cshtml and _Layout.cshtml were already coded properly.