未指定authenticationScheme,并且未找到具有默认身份validation和自定义授权的DefaultChallengeScheme

我有一个net core 2.0应用程序和授权问题。 我想使用特殊request.header和标准默认身份validation的自定义授权。 首先,我在startup.cs中添加配置:

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

和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; } } 

在HomeController.cs中

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

如果我在AuthTokenPolicy中使用错误的request.header,我会看到它。 但在日志中我看到错误:

System.InvalidOperationException:未指定authenticationScheme,并且未找到DefaultChallengeScheme。\ r \ n在Microsoft.AspNetCore.Authentication.AuthenticationService.d__11.MoveNext()\ r \ n —从上一个位置的堆栈跟踪结束抛出了— \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n,在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Mvc上。 ChallengeResult.d__14.MoveNext()\ r \ n —从抛出exception的上一个位置开始的堆栈跟踪结束—在系统上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n中的\ r \ n .Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__19.MoveNext()\ r \ n —从上一个引发exception的位置的堆栈跟踪结束— \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ nn \ na t System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext()\ r \ n —从上一个位置的堆栈跟踪结束抛出了— \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n,在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Mvc上。 Internal.ResourceInvoker.d__15.MoveNext()\ r \ n —从抛出exception的上一个位置开始的堆栈跟踪结束— \ r \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()\ r \ n — —从前一个位置抛出exception的堆栈跟踪结束— \ r \ n在System.Runtime.CompilerSe的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n中 在Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.d__3.MoveNext()\ r \ n中的rvices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n —从抛出exception的上一个位置开始的堆栈跟踪结束— \ r \ n \ n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在React.AspNet.BabelFileMiddleware.d__5.MoveNext()\ r \ n \ n —抛出exception的前一个位置的堆栈跟踪结束—在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n中的\ r \ n任务任务)\ r \ n在Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext()\ r \ n —从抛出exception的上一个位置的堆栈跟踪结束— \ r \ n在System.Runtime System.Runtime.CompilerServices.TaskAwaiter.Han中的.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n dleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在core.common.Middleware.LoggingMiddleware.d__3.MoveNext()在D:\ Dev \ microservicePDP \ Template \ core.common \ Middleware \ LoggingMiddleware.cs:第72行

阅读迁移身份validation和身份到ASP.NET Core 2.0之后,我在startup.cs中添加了此代码

文章引文:

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

如果满足下列条件之一,则在2.0中定义默认方案:您希望用户自动登录您使用[授权]属性或授权策略而不指定方案

我在ConfigureServices中添加了AuthenticationScheme和DefaultChallengeScheme。 这没有帮助,这里也是同样的错误。 我试过用过app.UseAuthentication(); 在StartUp.cs中的Configure中,没有结果。 有人可以解释如何使用自定义授权而无需身份validation吗?

好。 正确答案是:不要使用授权而不是validation。 我应该通过标题访问所有客户端。 工作代码是:

 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 

和mycontroller.cs

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

我现在找不到TokenAuthenticationOptions,但它是空的。 我找到了同一类PhoneNumberAuthenticationOptions:

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

您应该定义静态类SchemesNamesConst类似于:

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

在我使用策略之前,我也将默认的身份validation方案设置到其中。 我修改了DefaultPolicy因此略有不同。 但是同样适用于添加策略也是如此。

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

请考虑默认AuthenticationSchemes属性使用只读列表。 我认为最好实现它而不是List。