No se especificó authenticationScheme, y no se encontró DefaultChallengeScheme con la autenticación predeterminada y la autorización personalizada

Tengo una aplicación net core 2.0 y un problema con la autorización. Quiero usar la autorización personalizada con request.header especial y autenticación predeterminada estándar. Primero, agrego la configuración en startup.cs:

public IServiceProvider ConfigureServices(IServiceCollection services) { ... services.AddAuthorization(options => { options.AddPolicy(DefaultAuthorizedPolicy, policy => { policy.Requirements.Add(new TokenAuthRequirement()); }); }); services.AddSingleton(); ... } 

y AuthTokenPolicy.cs

 public class AuthTokenPolicy : AuthorizationHandler { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TokenAuthRequirement requirement) { var filterContext = context.Resource as AuthorizationFilterContext; var response = filterContext.HttpContext.Response; try { // some validation code var isValidToken = isValidTokenTask.Result; if (!isValidToken) { response.StatusCode = 401; return Task.CompletedTask; } response.StatusCode = 200; context.Succeed(requirement); } catch (Exception) { return Task.CompletedTask; } return Task.CompletedTask; } } 

y en HomeController.cs

 [Authorize(Policy = Startup.DefaultAuthorizedPolicy)] public async Task IsVisible() 

Si uso request.header incorrecto en AuthTokenPolicy lo veo. Pero en los registros veo error:

System.InvalidOperationException: No se especificó authenticationScheme, y no se encontró DefaultChallengeScheme. \ R \ n en Microsoft.AspNetCore.Authentication.AuthenticationService.d__11.MoveNext () \ r \ n — Fin del astackmiento desde la ubicación anterior donde se exceptúa se lanzó — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.ervilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tarea de tarea) \ r \ n en Microsoft.AspNetCore.MX.png ChallengeResult.d__14.MoveNext () \ r \ n — Fin del seguimiento de la stack desde la ubicación anterior donde se lanzó la excepción — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System .Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tarea de tarea) \ r \ n en Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__19.MoveNext () \ r \ n — Fin de la traza de la stack de la ubicación anterior donde se incluyó la excepción — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ na t System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (tarea de tarea) \ r \ n en Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext () \ r \ n — Fin del rastreo de stack de la ubicación anterior donde sea excepcional se lanzó — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.ervilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tarea de tarea) \ r \ n en Microsoft.AspNetCore.MX.png Internal.ResourceInvoker.d__15.MoveNext () \ r \ n — Fin del seguimiento de la stack desde la ubicación anterior donde se lanzó la excepción — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tarea) \ r \ n en Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext () \ r \ n — Fin del seguimiento de la stack de la ubicación anterior, donde se lanzó la excepción — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.CompilerSe rvices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tarea de tarea) \ r \ n en Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.d__3.MoveNext () \ r \ n — Final del astackmiento desde la ubicación anterior donde se produjo la excepción — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAileDebuggerNotification (Tarea de tarea) \ r \ n en React.AspNet.Beldo Evaciente paquete de correo electrónico. \ n — Fin del seguimiento de la stack de la ubicación anterior donde se lanzó la excepción — \ r \ n en System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification ( Tarea) \ r \ n en Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext () \ r \ n — Fin del seguimiento de la stack desde la ubicación anterior donde se lanzó la excepción — \ r \ n en System.Runtime .ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n en System.Runtime.CompilerServices.TaskAwaiter.Han dleNonSuccessAndDebuggerNotification (tarea) \ r \ n en core.common.Middleware.LoggingMiddleware.d__3.MoveNext () en D: \ Dev \ microservicePDP \ Template \ core.common \ Middleware \ LoggingMiddleware.cs: línea 72

Después de leer Migración de autenticación e identidad a ASP.NET Core 2.0 , agregué este código en startup.cs

Cita del artículo:

 services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }); 

Defina un esquema predeterminado en 2.0 si se cumple alguna de las siguientes condiciones: desea que el usuario inicie sesión automáticamente. Utilice el atributo [Autorizar] o las políticas de autorización sin especificar esquemas.

Agregué AuthenticationScheme y DefaultChallengeScheme en ConfigureServices. No fue de ayuda, el mismo error aquí. He intentado utilizar app.UseAuthentication (); en Configurar en StartUp.cs, no hay resultados. ¿Alguien puede explicar cómo usar la autorización personalizada sin autenticación?

Bueno. La respuesta correcta es: no utilice la autorización en lugar de la autenticación. Debería tener acceso al hoyo para atender a todos los clientes con encabezado El código de trabajo es:

 public class TokenAuthenticationHandler : AuthenticationHandler { public IServiceProvider ServiceProvider { get; set; } public TokenAuthenticationHandler (IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IServiceProvider serviceProvider) : base (options, logger, encoder, clock) { ServiceProvider = serviceProvider; } protected override Task HandleAuthenticateAsync () { var headers = Request.Headers; var token = "X-Auth-Token".GetHeaderOrCookieValue (Request); if (string.IsNullOrEmpty (token)) { return Task.FromResult (AuthenticateResult.Fail ("Token is null")); } bool isValidToken = false; // check token here if (!isValidToken) { return Task.FromResult (AuthenticateResult.Fail ($"Balancer not authorize token : for token={token}")); } var claims = new [] { new Claim ("token", token) }; var identity = new ClaimsIdentity (claims, nameof (TokenAuthenticationHandler)); var ticket = new AuthenticationTicket (new ClaimsPrincipal (identity), this.Scheme.Name); return Task.FromResult (AuthenticateResult.Success (ticket)); } } 

Startup.cs:

 #region Authentication services.AddAuthentication (o => { o.DefaultScheme = SchemesNamesConst.TokenAuthenticationDefaultScheme; }) .AddScheme (SchemesNamesConst.TokenAuthenticationDefaultScheme, o => { }); #endregion 

Y mycontroller.cs

 [Authorize(AuthenticationSchemes = SchemesNamesConst.TokenAuthenticationDefaultScheme)] public class MainController : BaseController { ...} 

No puedo encontrar TokenAuthenticationOptions ahora, pero estaba vacío. Encontré la misma clase PhoneNumberAuthenticationOptions:

 namespace Project.Auth{ public class PhoneNumberAuthenticationOptions : AuthenticationSchemeOptions { public Regex PhoneMask { get; set; }// = new Regex("7\\d{10}"); }} 

Deberías definir la clase estática SchemesNamesConst Algo como:

 namespace Common.Const{ public static class SchemesNamesConst { public const string SchemesNamesConst= "TokenAuthenticationScheme"; }} 

Cuando utilicé la política antes de configurar también el esquema de autenticación predeterminado. Había modificado la DefaultPolicy por lo que era un poco diferente. Sin embargo, lo mismo debería funcionar para agregar política también.

 services.AddAuthorization(options => { options.AddPolicy(DefaultAuthorizedPolicy, policy => { policy.Requirements.Add(new TokenAuthRequirement()); policy.AuthenticationSchemes = new List() { CookieAuthenticationDefaults.AuthenticationScheme } }); }); 

Tenga en cuenta que, por defecto, la propiedad AuthenticationSchemes usa una lista de solo lectura. Creo que sería mejor implementar eso en lugar de List también.