Ya no tienes que investigar más por todo internet ya que has llegado al sitio adecuado, poseemos la solución que buscas sin complicarte.
Solución:
¡Resuelto!
Seguí el ejemplo: MVC5-MixAuth
Créditos: Mohammed Younes
ACTUALIZACIÓN 1
Problema: Necesitaba tener ambos Autenticación anónima y Autenticación de Windows activado. Pero cuando los habilita a ambos, solo puede obtener AUTORIDAD DEL NT IUSR.
Resolución: Para obtener el usuario actual (introducido con el indicador NTLM), necesitamos crear un controlador que se ejecutará cuando un usuario ingrese a la página de inicio de sesión. Cuando el usuario accede a la página de inicio de sesión, el controlador obtendrá la identidad de Windows actual almacenada en caché en el navegador y luego se configurará como el LogonUserIdentity.
Nota: Necesitaba usar ventanas primero inicio de sesión, cuando el usuario ingresa a la página de inicio de sesión, intentará obtener el usuario ASP.NET correspondiente.
Manipulador
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.AspNet.Identity;
namespace MixedAuth
///
/// Managed handler for windows authentication.
///
public class WindowsLoginHandler : HttpTaskAsyncHandler, System.Web.SessionState.IRequiresSessionState
public HttpContext Context get; set;
public override async Task ProcessRequestAsync(HttpContext context)
this.Context = context;
//if user is already authenticated, LogonUserIdentity will be holding the current application pool identity.
//to overcome this:
//1. save userId to session.
//2. log user off.
//3. request challenge.
//4. log user in.
if (context.User.Identity.IsAuthenticated)
this.SaveUserIdToSession(context.User.Identity.GetUserId());
await WinLogoffAsync(context);
context.RequestChallenge();
else if (!context.Request.LogonUserIdentity.IsAuthenticated)
context.RequestChallenge();
else
// true: user is trying to link windows login to an existing account
if (this.SessionHasUserId())
var userId = this.ReadUserIdFromSession();
this.SaveUserIdToContext(userId);
await WinLinkLoginAsync(context);
else // normal login.
await WinLoginAsync(context);
#region helpers
///
/// Executes Windows login action against account controller.
///
///
///
private async Task WinLoginAsync(HttpContext context)
var routeData = this.CreateRouteData(Action.Login);
routeData.Values.Add("returnUrl", context.Request["returnUrl"]);
routeData.Values.Add("userName", context.Request.Form["UserName"]);
await ExecuteController(context, routeData);
///
/// Execute Link Windows login action against account controller.
///
///
///
private async Task WinLinkLoginAsync(HttpContext context)
var routeData = this.CreateRouteData(Action.Link);
await ExecuteController(context, routeData);
///
/// Executes Windows logoff action against controller.
///
///
///
private async Task WinLogoffAsync(HttpContext context)
var routeData = this.CreateRouteData(Action.Logoff);
await ExecuteController(context, routeData);
///
/// Executes controller based on route data.
///
///
///
///
private async Task ExecuteController(HttpContext context, RouteData routeData)
var wrapper = new HttpContextWrapper(context);
MvcHandler handler = new MvcHandler(new RequestContext(wrapper, routeData));
IHttpAsyncHandler asyncHandler = ((IHttpAsyncHandler)handler);
await Task.Factory.FromAsync(asyncHandler.BeginProcessRequest, asyncHandler.EndProcessRequest, context, null);
#endregion
Extensiones
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
namespace MixedAuth
public enum Action Login, Link, Logoff ;
public static class MixedAuthExtensions
const string userIdKey = "windows.userId";
//http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
const int fakeStatusCode = 418;
const string controllerName = "Account";
const string loginActionName = "WindowsLogin";
const string linkActionName = "LinkWindowsLogin";
const string logoffActionName = "WindowsLogoff";
const string windowsLoginRouteName = "Windows/Login";
public static void RegisterWindowsAuthentication(this MvcApplication app)
app.EndRequest += (object sender, EventArgs e) =>
HttpContext.Current.ApplyChallenge();
;
///
/// Registers ignore route for the managed handler.
///
///
public static void IgnoreWindowsLoginRoute(this RouteCollection routes)
routes.IgnoreRoute(windowsLoginRouteName);
///
/// By pass all middleware and modules, by setting a fake status code.
///
///
public static void RequestChallenge(this HttpContext context)
context.Response.StatusCode = fakeStatusCode;
///
/// Invoke on end response only. Replaces the current response status code with 401.2
///
///
public static void ApplyChallenge(this HttpContext context)
if (context.Response.StatusCode == fakeStatusCode)
context.Response.StatusCode = 401;
context.Response.SubStatusCode = 2;
//http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors(v=vs.110).aspx
//context.Response.TrySkipIisCustomErrors = true;
///
///
///
///
///
///
public static RouteData CreateRouteData(this WindowsLoginHandler handler, Action action)
RouteData routeData = new RouteData();
routeData.RouteHandler = new MvcRouteHandler();
switch (action)
case Action.Login:
routeData.Values.Add("controller", controllerName);
routeData.Values.Add("action", loginActionName);
break;
case Action.Link:
routeData.Values.Add("controller", controllerName);
routeData.Values.Add("action", linkActionName);
break;
case Action.Logoff:
routeData.Values.Add("controller", controllerName);
routeData.Values.Add("action", logoffActionName);
break;
default:
throw new NotSupportedException(string.Format("unknonw action value '0'.", action));
return routeData;
///
/// Saves userId to the items collection inside .
///
public static void SaveUserIdToContext(this WindowsLoginHandler handler, string userId)
if (handler.Context.Items.Contains(userIdKey))
throw new ApplicationException("Id already exists in context.");
handler.Context.Items.Add("windows.userId", userId);
///
/// Reads userId from item collection inside .
///
/// The item will removed before this method returns
///
///
public static int ReadUserId(this HttpContextBase context)
if (!context.Items.Contains(userIdKey))
throw new ApplicationException("Id not found in context.");
int userId = Convert.ToInt32(context.Items[userIdKey] as string);
context.Items.Remove(userIdKey);
return userId;
///
/// Returns true if the session contains an entry for userId.
///
public static bool SessionHasUserId(this WindowsLoginHandler handler)
return handler.Context.Session[userIdKey] != null;
///
/// Save a session-state value with the specified userId.
///
public static void SaveUserIdToSession(this WindowsLoginHandler handler, string userId)
if (handler.SessionHasUserId())
throw new ApplicationException("Id already exists in session.");
handler.Context.Session[userIdKey] = userId;
///
/// Reads userId value from session-state.
///
/// The session-state value removed before this method returns.
///
///
public static string ReadUserIdFromSession(this WindowsLoginHandler handler)
string userId = handler.Context.Session[userIdKey] as string;
if (string.IsNullOrEmpty(userIdKey))
throw new ApplicationException("Id not found in session.");
handler.Context.Session.Remove(userIdKey);
return userId;
///
/// Creates a form for windows login, simulating external login providers.
///
///
///
///
public static MvcForm BeginWindowsAuthForm(this HtmlHelper htmlHelper, object htmlAttributes)
return htmlHelper.BeginForm("Login", "Windows", FormMethod.Post, htmlAttributes);
///
/// Creates a form for windows login, simulating external login providers.
///
///
///
///
public static MvcForm BeginWindowsAuthForm(this HtmlHelper htmlHelper, object routeValues, object htmlAttributes)
return htmlHelper.BeginForm("Login", "Windows", FormMethod.Post, htmlAttributes);
Nota
Necesita tener AccountController.cs como parcial.
AccountController.Windows.cs
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.AspNet.Identity;
using MixedAuth;
namespace EmployeePortal.Web.Controllers
[Authorize]
public partial class AccountController : BaseController
HttpVerbs.Post)]
public ActionResult WindowsLogin(string userName, string returnUrl)
if (!Request.LogonUserIdentity.IsAuthenticated)
return RedirectToAction("Login");
var loginInfo = GetWindowsLoginInfo();
// Sign in the user with this external login provider if the user already has a login
var user = UserManager.Find(loginInfo);
if (user != null)
SignIn(user, isPersistent: false);
return RedirectToLocal(returnUrl);
else
return RedirectToAction("Login", new RouteValueDictionary(new controller = "Account", action = "Login", returnUrl = returnUrl ));
//
// POST: /Account/WindowsLogOff
[HttpPost]
[ValidateAntiForgeryToken]
public void WindowsLogOff()
AuthenticationManager.SignOut();
//
// POST: /Account/LinkWindowsLogin
[AllowAnonymous]
[HttpPost]
public async Task LinkWindowsLogin()
int userId = HttpContext.ReadUserId();
//didn't get here through handler
if (userId <= 0)
return RedirectToAction("Login");
HttpContext.Items.Remove("windows.userId");
//not authenticated.
var loginInfo = GetWindowsLoginInfo();
if (loginInfo == null)
return RedirectToAction("Manage");
//add linked login
var result = await UserManager.AddLoginAsync(userId, loginInfo);
//sign the user back in.
var user = await UserManager.FindByIdAsync(userId);
if (user != null)
await SignInAsync(user, false);
if (result.Succeeded)
return RedirectToAction("Manage");
return RedirectToAction("Manage", new Message = ManageMessageId.Error );
#region helpers
private UserLoginInfo GetWindowsLoginInfo()
if (!Request.LogonUserIdentity.IsAuthenticated)
return null;
return new UserLoginInfo("Windows", Request.LogonUserIdentity.User.ToString());
#endregion
public class WindowsLoginConfirmationViewModel
[Required]
[Display(Name = "User name")]
public string UserName get; set;
Luego, debe agregar el controlador:
Startup.cs
app.CreatePerOwinContext(dbEmployeePortal.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
app.CreatePerOwinContext(ApplicationSignInManager.Create);
PathString path = new PathString("/Account/Login");
if (GlobalExtensions.WindowsAuthActive)
path = new PathString("/Windows/Login");
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
//LoginPath = new PathString("/Account/Login")
LoginPath = path
);
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
Entonces necesitas configurar IIS local usar Autenticación de Windows y Autenticación anónima. Puede hacer esto en el Módulo de autenticación.
Nota Si no tienes Autenticación de Windows ir a Panel de control luego Programas y características luego "Activar o desactivar las funciones de Windows":
seleccione "Servicios de información de Internet"> "World Wide Web"> "Seguridad" y seleccione Autenticación de Windows.
No vi esto en su respuesta, por lo que para cualquiera que busque cómo capturar Windows Auth en su canalización Owin, también puede agregar lo siguiente a su ConfigureAuth
método:
public void ConfigureAuth(IAppBuilder app)
HttpListener listener = (HttpListener)app.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
Reseñas y valoraciones
Recuerda que tienes la opción de agregar una reseña .