c# - español - ASP.NET Core 2.0 HttpSys La autenticación de Windows falla con el atributo Autorizar(InvalidOperationException: no se especificó authenticationScheme)
asp.net core authentication (2)
Estoy intentando migrar una aplicación ASP.NET Core 1.1 a ASP.NET Core 2.0.
La aplicación es bastante simple e implica lo siguiente:
- Alojado en HttpSys (anteriormente WebListener)
- Usando la autenticación de Windows:
options.Authentication.Schemes = AuthenticationSchemes.NTLM
- Permitir autenticación anónima:
options.Authentication.AllowAnonymous = true
(porque hay algunos controladores que no requieren autenticación) - Los controladores que requieren autenticación están decorados con el atributo
[Authorize]
.
El proyecto se compila y comienza muy bien. También sirve acciones de controladores que no requieren autenticación.
Sin embargo, tan pronto como toco un controlador con el atributo [Authorize]
, obtengo la siguiente excepción:
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()
Empecé a jugar con las plantillas de proyecto y noté que podía reproducir esto fácilmente usando la plantilla estándar ASP.NET Core Web Application (Modelo-Vista-Controlador) con Autenticación de Windows.
El archivo Program.cs se modificó de la siguiente manera:
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();
Esto viene directamente de la documentación HttpSys . También agregué el atributo [Authorize]
a la clase HomeController
. Ahora, producirá exactamente la misma excepción que se muestra.
Encontré algunas publicaciones relacionadas de Desbordamiento de pila ( aquí , aquí y aquí ), pero ninguna de ellas trata sobre la Autenticación simple de Windows (y las respuestas no parecen generalizarse).
La respuesta de Andreas me puso en el camino correcto, pero esto es lo que funcionó para mí:
Se agregó una referencia de paquete a Microsoft.AspNetCore.Authentication
y luego para Startup.cs
using Microsoft.AspNetCore.Server.IISIntegration;
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(IISDefaults.AuthenticationScheme);
...
}
Mientras escribía la publicación, recordé encontrar esta subsección de la guía de migración. Dice agregar
services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);
a la función ConfigureServices
.
Inicialmente pensé que esto no se aplicaría a HttpSys, dado el nombre completo de la constante (especialmente el IISIntegration
me echó). Además, a partir de este escrito, la documentación HttpSys no menciona esto por completo.
Para aquellos que apuntan al .NET Framework completo, esto requiere la instalación del paquete NuGet de Microsoft.AspNetCore.Authentication
.
EDITAR
Como señala Tratcher, hay una constante similar del espacio de nombres HttpSys
que deberías usar:
Microsoft.AspNetCore.Server.HttpSys.HttpSysDefaults.AuthenticationScheme