web-dev-qa-db-ja.com

ASP.Netコア2:デフォルトの認証スキームは無視されました

ASP.Net Core 2でカスタムAuthenticationHandlerを構築しようとしています。 ASP.NET Core 2.0認証ミドルウェア および Asp.Net Core認証方式が必須である理由 などのトピックをフォローしています。 =、特定のクラスを作成しました。登録は次のように行われます:

services.AddAuthentication(
    options =>
    {
        options.DefaultScheme = Constants.NoOpSchema;
        options.DefaultAuthenticateScheme = Constants.NoOpSchema;
        options.DefaultChallengeScheme = Constants.NoOpSchema;
        options.DefaultSignInScheme = Constants.NoOpSchema;
        options.DefaultSignOutScheme = Constants.NoOpSchema; 
        options.DefaultForbidScheme = Constants.NoOpSchema;
    }
).AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });

特定のコントローラーがスキームを明示的に設定した場合、すべてが機能します。

[Authorize(AuthenticationSchemes= Constants.NoOpSchema)]
[Route("api/[controller]")]
public class IndividualsController : Controller

しかし、スキーマを動的に追加する必要があるため、スキーマを設定する必要はありません。次のように、Schemeプロパティを削除するとすぐに:

[Authorize]
[Route("api/[controller]")]
public class IndividualsController : Controller

それはもう機能しません。

DefaultSchemeプロパティを設定することでこの仕事ができることを期待していました。興味深いことに、このトピックに関する具体的な議論は見つかりませんでした。ここで何か間違っているのですか、それとも私の予想される結果は間違っていますか?

編集:質問をありがとう、それは私を大いに助けました。 DefaultAuthchemeのマッピングは、CustomAuthHandlerが配置されていないときに、私が使用した認証ミドルウェアによって使用されているようです。したがって、AuthenticationMiddlewareを常に追加する必要がありました。

Edit2:残念ながら、それでも動作しません。私の質問を少し強調するために、私はいつものようにミドルウェアを追加しています:

app.UseAuthentication();
app.UseMvc();

次に、ハンドラーに入ります。ハンドラーは次のようになります。

public class NoOpAuthHandler : AuthenticationHandler<NoOpAuthOptions>
{
    public const string NoOpSchema = "NoOp";

    public NoOpAuthHandler(IOptionsMonitor<NoOpAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync() => Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, NoOpSchema)));
}

しかし、常に成功を返す場合でも、401を取得します。より深く掘り下げて、いくつかのクレームを設定する必要があると思いますが、残念ながら、Microsoftのハンドラーにはコードが多く含まれているため、分析が非常に困難です。

14

ASP.Net Core 2回答

認証スキームに関連付けられたデフォルトの許可ポリシーを設定する必要があります。

services.AddAuthorization(options => {
  options.DefaultPolicy = new AuthorizationPolicyBuilder()
    .AddAuthenticationSchemes(Constants.NoOpSchema)
    .RequireAuthenticatedUser()
    .Build();
});

ASP.Net Core 3回答

ASP.Net Core 3では、明らかに少し変更されたため、拡張メソッドを作成して認証ハンドラーを追加する必要があります。

public static class NoOpAuthExtensions
{
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, _ => { });
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(authenticationScheme, null, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<NoOpAuthOptions> configureOptions)
    {
        return builder.AddScheme<NoOpAuthOptions, NoOpAuthHandler>(authenticationScheme, displayName, configureOptions);
    }
}

次のように、ConfigureServicesメソッドで使用します。

services
  .AddAuthentication(NoOpAuthHandler.NoOpSchema)
  .AddNoOpAuth();
12
RaphaelH

パイプラインに認証ミドルウェアがあることを確認し、MVCの前に配置します。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ///

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });
    ///
}

[〜#〜]更新[〜#〜]

このコードをHandleAuthenticateAsyncメソッドで使用してみてください。

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    List<Claim> claims = new List<Claim>();
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
    ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);
    return AuthenticateResult.Success(authenticationTicket);
}
10
Kahbazi

これを試して。

services.AddAuthentication(
        options =>
        {
            options.DefaultAuthenticateScheme = "Cookie"
            options.DefaultChallengeScheme = Constants.NoOpSchema;
            options.DefaultSignInScheme = "Cookie";
        }
    )
    .AddCookie("Cookie")
    .AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });
0
Oleg