2017-03-23 93 views
0

我有一个ASP.Net MVC 5应用程序,目前使用个人身份验证(帐户/ l​​ogin.cshtml页面没有身份验证/匿名访问)和OWIN。工作正常。ASP.Net MVC - OWIN - 允许Windows /个人身份验证

由于这是一个Intranet应用程序,我希望允许用户在他们的Windows帐户,其他用户Windows帐户或应用程序帐户(管理员,特殊用户等)登录 - 这些帐户没有关联的域帐户。

对于第一个选项,我想在登录屏幕上显示他们的Windows用户名,他们只需点击“确定”按钮即可登录。要获取用户名,我修改了Visual Studio项目属性以禁用匿名身份验证并启用Windows身份验证。还修改了web.config并将身份验证模式设置为Forms。这会导致“HTTP错误404.15 - 未找到”。这似乎是由于由OWIN引起的验证循环,并带有以下修复建议:

  • 确保登录控制器方法允许匿名访问(默认情况下似乎是这种方式)。
  • 或修改Startup.auth,注销LoginPath属性。
  • 或者修改web.config,添加值为“false”的appSetting“owin:AutomaticAppStartup”。

我选择了LoginPath修复,这似乎工作(如web.config更改),因为没有错误,登录页面显示与Windows用户名(使用System.Threading.Thread.Currentprinciple检索.Identity.Name)。

现在的问题是,一旦用户登录OwinContext没有用户(HttpContext.GetOwinContext()。GetUserManager())。

理想情况下,我不需要IIS或OWIN进行任何身份验证,因为它是由应用完成的 - 但我需要初始请求(对于帐户/登录页面)包含Authenticate头部,以便可以获取Windows用户。

首先我想了解是什么导致“HTTP错误404.15”并修复。 其次,我如何让OWIN与认证更改一起工作 - 我只是需要它来坚持用户进行控制器认证。

回答

0

这只是一个猜测,但我相信错误是由您描述的错误配置引起的:您已将身份验证模式设置为“Forms”,但将项目设置为使用Windows身份验证。它可能会令人困惑,但Windows身份验证不是表单身份验证。当你使用表单认证时,用户提供表单中提交的凭证,并对用户存储进行验证(包括所有的防伪功能)(我相信你使用的是ASP.NET身份验证,这是默认的“个人身份验证“设置),如果验证成功,则设置的cookie将包含在响应中。这个cookie然后被用来认证更多的请求。

Katana documentation确认,没有内置的Windows身份验证中间件 - 微软只是假设应该使用IIS。这有效地阻止了我们从很容易结合Katana OWIN中间件供应商与Windows身份验证。现在,关键词很容易:我们仍然可以“绕过”它的方式。

不幸的是,它仍然是一个黑客:我还没有找到一种方法来使认证“透明”(如在“”用户打开登录表单并且可以输入AD帐户凭证或个人帐户凭证和一切正常工作“)。您需要为每个Windows用户维护个人帐户记录(就像您使用任何外部OWIN中间件(例如Google或Facebook)一样)。您可以自动完成帐户创建和关联,并使其看起来透明。您可以为Windows身份验证添加一个“外部提供者”按钮。

验证用户看起来像(在一个单独的“AD认证”控制器):

bool userWindowsAuthentication = Request.LogonUserIdentity.IsAuthenticated; 

if (userWindowsAuthentication) { 
    var userStoreDatabaseContext = new ApplicationDbContext(); 
    var userStore = new UserStore<UserModel>(userStoreDatabaseContext); 
    var userStoreManager = new UserManager<UserModel>(userStore); 
    var userWindowsLoginCredentials = GetWindowsLoginInfo(); 

    var existingInternalUser = userStoreManager.FindAsync(userWindowsLoginCredentials.UserName) 

    if (existingInternalUser) { 
     // It means that the user already exists in the internal provider and here you simply authenticate and redirect to destination 
    } else { 
     // It means that the user does not exist. You can automatically create the internal user record here and associate the Windows user with the internal record. 
    } 
} else { 
    // It means that user is not signed in using Windows authentication, so you either want to redirect back to the login page or restrict access or do something else 
} 

正如你可以看到,它的“脏”。另一个黑客:你可以有只接受Windows身份验证的附加层(单独的应用程序或虚拟应用程序)。这个应用程序可以是您的登录资源。如果用户使用Windows AD进行身份验证,则可以将其重定向到正确的登录页面。你可以走得更远,并在重定向请求头中添加他们的登录信息,但如果你这样做 - 头部必须加密,以确保Windows身份验证不能伪造,唯一应该能够解密和验证它的应该是你的主要应用。再次,肮脏,但工程。

+0

感谢您的快速反应Phil.P.我已经尝试了Forms和Windows身份验证,并且都产生了相同的结果。请注意 - 我需要的所有Windows身份验证都是在初始请求中传递客户端用户名 - 然后,如果Windows用户在数据库和LDAP查询中对用户表进行身份验证。 –

+0

@ Leigh.D你打算如何验证LDAP?什么阻止我作为黑客来取代我通过已知Windows用户名传递的内容并进行有效验证? Windows身份验证是指验证实际用户身份验证的NTLM。您必须在“使用个人帐户”中使用Forms,项目设置,并使用其他auth端点/中间件进行Windows身份验证。 –