简体   繁体   English

ASP.Net MVC-OWIN-允许Windows /个人身份验证

[英]ASP.Net MVC - OWIN - Allowing Windows/Individual Authentication

I have an ASP.Net MVC 5 application which is currently using individual authentication (account/login.cshtml page with no authentication/anonymous access) and OWIN. 我有一个ASP.Net MVC 5应用程序,该应用程序当前正在使用单独的身份验证(没有身份验证/匿名访问的account / login.cshtml页面)和OWIN。 Works fine. 工作正常。

As this is an intranet app I want to allow the users to log in under their windows account, another users windows account or an application account(admin, special user etc. - these accounts have no associated domain account). 由于这是一个Intranet应用程序,因此我希望允许用户使用其Windows帐户,另一个用户Windows帐户或应用程序帐户(管理员,特殊用户等-这些帐户没有关联的域帐户)登录。

For the first option I wanted to display their windows username on the login screen and they can simply click the "ok" button to login. 对于第一个选项,我想在登录屏幕上显示其Windows用户名,他们只需单击“确定”按钮即可登录。 To get the username I modified the Visual Studio Project properties to disable anonymous authentication and enable windows authentication. 为了获得用户名,我修改了Visual Studio Project属性以禁用匿名身份验证并启用Windows身份验证。 Also modified the web.config and set the authentication mode to Forms. 还修改了web.config并将身份验证模式设置为Forms。 This causes "HTTP Error 404.15 - Not Found". 这将导致“ HTTP错误404.15-未找到”。 This appears to be due to an authentication loop caused by OWIN with the following suggestions to fix: 这似乎是由于OWIN导致的身份验证循环而导致的,以下修复建议:

  • Ensure Login controller methods allow anonymous access (seems to be this way by default). 确保登录控制器方法允许匿名访问(默认情况下似乎是这种方式)。
  • or Modify Startup.auth, comment out the LoginPath property. 或修改Startup.auth,注释掉LoginPath属性。
  • or Modify the web.config, add the appSetting "owin:AutomaticAppStartup" with value "false". 或修改web.config,添加值为“ false”的appSetting“ owin:AutomaticAppStartup”。

I opted for the LoginPath fix and this appears to work (as does web.config change) in that there are no errors and the login page displays with the windows username (retrieved using System.Threading.Thread.Currentprinciple.Identity.Name). 我选择了LoginPath修复,它似乎可以正常工作(web.config也是如此),因为没有错误,并且登录页面显示的是Windows用户名(使用System.Threading.Thread.Currentprinciple.Identity.Name检索)。

The problem is now that once the user has logged in the OwinContext has no user ( HttpContext.GetOwinContext().GetUserManager()). 现在的问题是,一旦用户登录OwinContext,便没有用户(HttpContext.GetOwinContext()。GetUserManager())。

Ideally I don't need IIS or OWIN doing any authentication as it's done by the app - but I need the initial request (for the account/login page) to include the Authenticate headers so I can get the windows user. 理想情况下,我不需要IIS或OWIN进行任何由应用程序完成的身份验证-但我需要初始请求(针对帐户/登录页面)包括Authenticate标头,这样我才能获得Windows用户。

Firstly I would like to understand what causes the "HTTP Error 404.15" and fix. 首先,我想了解导致“ HTTP错误404.15”并修复的原因。 Secondly, how do I get OWIN to work with the authentication change - I just need it to persist the user for controller authentication. 其次,如何使OWIN与身份验证更改配合使用-我只需要它来保留用户以进行控制器身份验证。

This is just a guess but I believe the error is caused by the misconfiguration you've described: you have set the authentication mode to "Forms" but set the project to use Windows Authentication. 这只是一个猜测,但我认为该错误是由您所描述的错误配置引起的:您已将身份验证模式设置为“窗体”,但将项目设置为使用Windows身份验证。 It can be confusing but Windows Authentication is not Forms Authentication. 可能会造成混淆,但是Windows身份验证不是表单身份验证。 When you are using Forms Authentication the user provides the credentials in the form that is submitted, validated (including all anti-forgery goodness) against the user store (I believe you are using ASP.NET Identity which would be a default for "Individual Authentication" setting) and if the validation is successful a cookie to set is included in the response. 当您使用表单身份验证时,用户将根据用户存储(我相信您使用的是ASP.NET Identity)提供已提交,已验证(包括所有防伪优势)的表单中的凭据,这将是“个人身份验证”的默认设置(设置),如果验证成功,则响应中将包含要设置的Cookie。 This cookie is then used to authenticate further requests. 然后,此cookie用于验证其他请求。

As confirmed by Katana documentation , there is no built-in middleware for Windows Authentication - Microsoft simply assumes that IIS should be used for that. 正如Katana文档所证实的那样,没有用于Windows身份验证的内置中间件-Microsoft只是假定应该使用IIS。 Which effectively prevents us from easily combining Katana OWIN middleware providers with Windows authentication. 这有效地阻止了我们轻松地将Katana OWIN中间件提供程序与Windows身份验证结合在一起。 Now, easily is the key word: we still can "hack" our way around it. 现在,关键词很容易:我们仍然可以“破解”它的方法。

Unfortunately, it still will be a hack: I have not found a way to make the authentication "transparent" (as in " a user opens the login form and can enter both the AD account credentials or the individual account credentials and everything just works "). 不幸的是,这仍然是一个黑客:我还没有找到一种使身份验证“透明”的方法(如“ 用户打开登录表单并可以输入AD帐户凭据或个人帐户凭据,并且一切正常 ”) )。 You will need to maintain the individual account record for every Windows user (as you would do with any external OWIN middleware, such as Google or Facebook). 您将需要维护每个Windows用户的个人帐户记录(就像使用任何外部OWIN中间件(例如Google或Facebook)一样)。 You can automate the account creation and association though and make it look transparent. 您可以自动执行帐户创建和关联,并使它看起来透明。 You can add an "external provider" button for your Windows authentication. 您可以为Windows身份验证添加“外部提供程序”按钮。

Authenticating the user would look like (in a separate "AD Authentication" controller): 验证用户的样子(在单独的“ 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
}

As you can see, it's "dirty". 如您所见,这是“肮脏的”。 Another hack: you can have additional layer (separate application or a virtual application) that accepts only Windows authentication. 另一个技巧:您可以拥有仅接受Windows身份验证的其他层(单独的应用程序或虚拟应用程序)。 This app can be your log-in resource. 该应用程序可以作为您的登录资源。 If the user is authenticated with Windows AD you can redirect them to the correct login page. 如果用户通过Windows AD进行了身份验证,则可以将其重定向到正确的登录页面。 You can go even further and add their login info in the redirect request header but if you do so - the header must be encrypted to ensure that Windows authentication cannot be faked and the only thing that should be able to decrypt and validate it should be your main application. 您可以走得更远,并在重定向请求标头中添加其登录信息,但如果这样做-标头必须经过加密,以确保Windows身份验证不会被伪造,并且唯一能够解密和验证它的人应该是您主要应用。 Again, dirty, but works. 再次,肮脏,但有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM