I am using windows authentication impersonation in my MVC application.when i open the application the browser display a prompt for the credentials and validate the domain users.
If I understand you correctly, you want to allow both Windows Authentication and Forms Authentication. This is not a common thing to do, but I have done it. Here is how I did it:
You have to use forms authentication as your primary authentication. So build the Forms Authentication as you normally would: you have a login page that, after submitting, validates the credentials from your database. The tricky part is adding Windows Authentication.
To do this, create one action in your authentication controller that uses Windows authentication. For this example, I'll assume your controller is AuthController
and we'll call the action WinLogin
. That action will look something like this:
[Authorize]
public ActionResult WinLogin() {
var principal = HttpContext.User;
if (principal == null || !principal.Identity.IsAuthenticated) {
//Windows authentication failed
return new HttpUnauthorizedResult();
}
// User is validated, so create the form authentication cookie
FormsAuthentication.SetAuthCookie(principal.Identity.Name, false);
return new EmptyResult();
}
It just checks if the user is validated and, if so, sets the Forms Authentication cookie with their AD username.
For that to use Windows Authentication, you have to update your web.config to tell it to use Windows Authentication for only that one action. You do that with a <location>
tag:
<location path="Auth/WinLogin">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
By default, IIS won't let you change the authentication method at this place in the config. You need to update the "Feature Delegation" in IIS Manager to allow it.
If you use IIS Express for debugging, you have to do something similar for that:
.vs\config\applicationhost.config
."Allow"
:<section name="anonymousAuthentication" overrideModeDefault="Allow" />
<section name="windowsAuthentication" overrideModeDefault="Allow" />
Next update your login page to hide the username and password fields by default (let's say they are inside a box with an id of loginBox
). The idea is that you perform an AJAX request to the WinLogin
action, and if that succeeds, then you forward the user on to the main page or whichever page they were trying to go to. If you use jQuery, that will look something like this:
$.get("@Url.Action("WinLogin", "Auth")")
.done(function() {
//success! forward to the page they want
window.location.replace(returnUrl);
}).fail(function() {
//failed - show manual login prompt
$("#loginBox").show();
});
});
As long as your website is already a trusted website (which I assume so if you already have Windows Authentication working now), then the Windows Authentication will happen during that AJAX GET request.
Notice the use of window.location.replace(), which will not add the login page to the browser history, so if the user then hits the back button, they do not come back to the login page. It makes things a little more seamless.
You could also add a loading circle or something to indicate that the user should wait while that GET happens, but you can decide that.
With all this in place, the user experience should be: