1. ホーム
  2. c#

[解決済み] authenticationScheme が指定されておらず、デフォルト認証とカスタム認証で DefaultChallengeScheme が見つかりませんでした。

2022-02-07 21:48:32

質問

.NET Core 2.0アプリを持っていますが、認証に問題があります。特別なリクエストでカスタム認証を使用したいのですが、どうすればいいですか?ヘッダーと標準的なデフォルトの認証。 まず、私は設定を Startup.cs :

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

AuthTokenPolicy.cs :

public class AuthTokenPolicy : AuthorizationHandler<TokenAuthRequirement>
{   
    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<IActionResult> IsVisible()

で間違ったrequest.headerを使用した場合 AuthTokenPolicy 見ているのですが、ログではこのようなエラーが出ています。

System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.\ at Microsoft.AspNetCore.Authentication.AuthenticationService.d__11.MoveNext()\r__n--- End of stack trace from previous location where exception was thrown ---##n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r__n at System.Runtime.CompilerServices.TaskAwaiter.DefaultDispatchInfo.MoveNet()### ###token@SystemRuntime_CompilerService.Throw()###at symfony@SystemRuntime_AuthenticationServices.Throw()###at SYSTEM_RINT HandleNonSuccessAndDebuggerNotification(Task task)\ at Microsoft.AspNetCore.Mvc.ChallengeResult.d__14.MoveNext()\n--- End of stack trace from previous location where exception was thrown [email protected]() at Microsoft.Runtime.CompilerServices.TaskAnnotification(Task task) Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.D__14.MoveNext() at Microsoft.Runtime.ExpressionService.ExceptionDispatchInfo.Throw()|SyncStatus d__19.MoveNext()\n--- End of stack trace from previous location where exception was thrown [email protected]()\n at System.Runtime.CompilerServices.TaskAwaiter.Throw()at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()@SystemRunting.CompilerServices.TaskAwaiter.Desrow()@SystemRunnting.Desrow() HandleNonSuccessAndDebuggerNotification(Task task)\rn at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext()\rn--- End of stack trace from previous location where exception was thrown ---System.Runtime.CompilerServices.TaskAwaiter.Throw() at System.Runtime.Custom Customization() at System.Customization() at System.Customization() at System.Customization() Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r__n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r__n at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__15.MoveNext()\r³³n--- End of stack trace from previous location where exceptions was thrown ----EEk at System.Runtime.ExceptionServices.Throw()|SystemRunitem.ExceptionServices.TaskAnitem.MoveNext()|ExtraStackTrace at SystemRunnitem.ExceptionInvoker.Moven()|ArtSuccessAnitem.Throw()|ArtStackTrace このとき、スタックトレースで例外が発生した場所の末尾に---- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4. MoveNext()↵ 例外を発生させた位置からスタックトレース終了 ---↵ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()↵ at System.Runtime.CompilerServices.TaskAwaiter.HandleWonAccessAndDebuggerNotification(Task task) HandleNonSuccessAndDebuggerNotification(Task task)\ at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.d__3.MoveNext()\n--- End of stack trace from previous location where exception was thrown ---System.Runtime.CompilerServices.TaskAwaiter.Utilization() at Microsoft.Runtime.Customization() at System.Runtime.Customization() at System.Customization() { {SystemRun.CodePagesMiddleware.d__3}. Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at React.NetSuccessAndDebuggerNotification(Task Task Task)|n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Release() At React.AspNet.BabelFileMiddleware.d__5.MoveNext()\rrn--- End of stack trace from previous location where exception was thrown ---■ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.End of stack trace from the previous location where exception was thrown ---■ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.MoveNext() Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.Throw()at System.Runtime.CompilerServices.ExceptionDispatchInfo. MoveNext()↵ 例外を発生させた位置からスタックトレースを終了する [email protected]()↵@System.Runtime.CompilerServices.HandleNonAaitgerNotification(Task task) TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\rn at core.common.Middleware.LoggingMiddleware.d__3.MoveNext() in D:³³Dev³microservicePDP³Template³core.common³Middleware³³LoggingMiddleware³.cs:line 72

を読んで ASP.NET Core 2.0への認証とアイデンティティの移行 startup.csに以下のコードを追加しました。

記事からの引用 :

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

以下の条件のいずれかに当てはまる場合、2.0のデフォルトスキームを定義します。 ユーザを自動的にサインインさせたい スキームを指定せずに [Authorize] 属性または認可ポリシーを使用する場合。

を追加しました。 AuthenticationSchemeDefaultChallengeSchemeConfigureServices() . こちらも同じエラーで、役に立ちませんでした。私は app.UseAuthentication(); の中に Startup.Configure() メソッドを実行しましたが、結果は得られませんでした。

認証なしでカスタム認証を使用するにはどうすればよいですか?

解決方法を教えてください。

認証の代わりに認可を使用しないでください。ヘッダを持つすべてのクライアントにサービスを提供するための全体的なアクセス権を取得する必要があります。

動作するコードは

public class TokenAuthenticationHandler : AuthenticationHandler<TokenAuthenticationOptions> 
{
    public IServiceProvider ServiceProvider { get; set; }

    public TokenAuthenticationHandler (IOptionsMonitor<TokenAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IServiceProvider serviceProvider) 
        : base (options, logger, encoder, clock) 
    {
        ServiceProvider = serviceProvider;
    }

    protected override Task<AuthenticateResult> 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<TokenAuthenticationOptions, TokenAuthenticationHandler> (SchemesNamesConst.TokenAuthenticationDefaultScheme, o => { });
#endregion

そして、mycontroller.cs。

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

TokenAuthenticationOptionsは今は見当たりませんが、空でした。同じクラスのPhoneNumberAuthenticationOptionsは見つかりました。

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

静的クラスを定義する必要があります。 SchemesNamesConst . みたいな感じ。

public static class SchemesNamesConst
{
    public const string TokenAuthenticationDefaultScheme = "TokenAuthenticationScheme";
}