简体   繁体   English

ASP.NET Core 2.0 HttpSys Windows 身份验证因 Authorize 属性而失败(InvalidOperationException:未指定身份验证方案)

[英]ASP.NET Core 2.0 HttpSys Windows Authentication fails with Authorize attribute (InvalidOperationException: No authenticationScheme was specified)

I am trying to migrate an ASP.NET Core 1.1 application to ASP.NET Core 2.0.我正在尝试将 ASP.NET Core 1.1 应用程序迁移到 ASP.NET Core 2.0。

The application is fairly simple and involves the following:该应用程序相当简单,涉及以下内容:

  • Hosted on HttpSys (formerly WebListener)托管在 HttpSys(以前的 WebListener)上
  • Using Windows authentication: options.Authentication.Schemes = AuthenticationSchemes.NTLM使用 Windows 身份验证: options.Authentication.Schemes = AuthenticationSchemes.NTLM
  • Allowing anonymous authentication: options.Authentication.AllowAnonymous = true (because there are some controllers that do not require authentication)允许匿名认证: options.Authentication.AllowAnonymous = true (因为有些控制器不需要认证)
  • Controllers that require authentication are decorated with the [Authorize] attribute.需要身份验证的控制器用[Authorize]属性修饰。

The project compiles and starts up just fine.该项目编译并启动得很好。 It also serves actions of controllers that do not require authentication.它还为不需要身份验证的控制器提供服务。

However, as soon as I hit a controller with the [Authorize] attribute, I get the following exception:但是,一旦我使用[Authorize]属性点击控制器,就会出现以下异常:

System.InvalidOperationException: No authenticationScheme was specified,
and there was no DefaultChallengeScheme found.
   at Microsoft.AspNetCore.Authentication.AuthenticationService.<ChallengeAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ChallengeResult.<ExecuteResultAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeResultAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

I started fiddling around with the project templates and noticed that I could reproduce this easily using the standard template ASP.NET Core Web Application (Model-View-Controller) with Windows Authentication.我开始摆弄项目模板,并注意到我可以使用带有 Windows 身份验证的标准模板ASP.NET Core Web 应用程序(模型-视图-控制器)轻松重现这一点。

The Program.cs file was changed as follows: Program.cs 文件更改如下:

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseHttpSys(options =>
            {
                options.Authentication.Schemes = AuthenticationSchemes.NTLM;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = 100;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5000");
            })
            .UseStartup<Startup>()
            .Build();

This comes straight from the HttpSys documentation .这直接来自HttpSys 文档 Also I added the [Authorize] attribute to the HomeController class.我还向HomeController类添加了[Authorize]属性。 Now, it will produce exactly the same exception as shown.现在,它将产生与所示完全相同的异常。

I found some related Stack Overflow posts ( here , here and here ), but none of them deals with plain Windows Authentication (and the answers do not seem to generalize).我发现了一些相关的 Stack Overflow 帖子( hereherehere ),但它们都没有处理普通的 Windows 身份验证(而且答案似乎没有概括)。

While writing up the post, I remembered coming across this subsection of the migration guide.在写这篇文章时,我记得遇到过迁移指南的这个小节 It says to add它说要添加

services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);

to the ConfigureServices function.ConfigureServices函数。

I initially thought that this wouldn't apply to HttpSys, given the full name of the constant (especially the IISIntegration threw me off).我最初认为这不适用于 HttpSys,考虑到常量的全名(尤其是IISIntegration让我失望)。 Moreover, as of this writing, the HttpSys documentation completely fails to mention this.此外,在撰写本文时, HttpSys 文档完全没有提及这一点。

For those targeting the full .NET Framework, this requires installing the Microsoft.AspNetCore.Authentication NuGet Package.对于面向完整 .NET Framework 的用户,这需要安装Microsoft.AspNetCore.Authentication NuGet 包。

EDIT编辑

As Tratcher points out, there is a similar constant from the HttpSys namespace you should rather use:正如 Tratcher 所指出的,您应该使用HttpSys命名空间中的一个类似常量:

Microsoft.AspNetCore.Server.HttpSys.HttpSysDefaults.AuthenticationScheme

Andreas' answer got me on the right path but this is what worked for me:安德烈亚斯的回答让我走上了正确的道路,但这对我有用:

Added package reference to Microsoft.AspNetCore.Authentication添加了对Microsoft.AspNetCore.Authentication的包引用

and then for Startup.cs然后对于Startup.cs

using Microsoft.AspNetCore.Server.IISIntegration;

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddAuthentication(IISDefaults.AuthenticationScheme);
    ...
}

Another thing, if you've already added services.AddAuthentication(IISDefaults.AuthenticationScheme);另一件事,如果您已经添加了services.AddAuthentication(IISDefaults.AuthenticationScheme); make sure to turn on an authentication type (windows, forms) in IIS under the app → authentication.确保在应用程序→身份验证下的 IIS 中打开身份验证类型(窗口、表单)。

Mine were all disabled and was getting this error even with the code in place.我的都被禁用了,即使代码到位,也会出现这个错误。

If it's still not working, make sure you configured launchsettings.json如果仍然无法正常工作,请确保您配置了 launchsettings.json

{
  "iisSettings": {
    //...
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    //...
  },
  "profiles": {
    "IIS Express": {
   //...
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    //...
    }
  }
  //...more stuff
}

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

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