netcore api 3.1でAuthorizationFilterContextを読み取る


9

APIキーをチェックするカスタムポリシーを実装したnetcore 2.2プロジェクトが機能しています。

startup.csに私はこのようにこのポリシーを追加しています

//Add Key Policy
services.AddAuthorization(options =>
{
    options.AddPolicy("AppKey", policy => policy.Requirements.Add(new AppKeyRequirement()));
});

私のAppKeyRequirementでは、AuthorizationHandlerから継承し、次のように着信リクエストのキーを解決します

protected override Task HandleRequirementAsync(AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
{
    var authorizationFilterContext = (AuthorizationFilterContext)authContext.Resource;
    var query = authorizationFilterContext.HttpContext.Request.Query;

    if (query.ContainsKey("key") && query.ContainsKey("app"))
    { // Do stuff

これはnetcore 3.1では機能しません

次のエラーが発生します。

タイプ「Microsoft.AspNetCore.Routing.RouteEndpoint」のオブジェクトをタイプ「Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext」にキャストできません。

コア3以上でこれを行う正しい方法は何ですか?

Kirk Larkinが指摘したように、.net 3.0以降での正しい方法は、IHttpContextAccessorをAuthハンドラーに挿入して使用することです。

この時点での私の質問は、これをどのように注入するのですか?これをstartup.csで渡すことはできません。少なくとも方法はわかりません。

どんなアイデア/ヒントも大歓迎です。

回答:


14

ASP.NET Core 3.0より前のバージョンでIAuthorizationHandlerは、の実装はMVCパイプライン中に呼び出されました。エンドポイントルーティング(デフォルト)を使用する3.0以降では、これらの実装は承認ミドルウェア(UseAuthorization())によって呼び出されます。このミドルウェアは、MVCパイプラインの一部としてではなく、その前に実行されます。

この変更は、AuthorizationFilterContext承認ハンドラに渡されなくなったことを意味します。代わりに、RouteEndpointへのアクセスを提供しないのインスタンスですHttpContext

あなたの例では、あなたはAuthorizationFilterContextを手に入れるためだけに使っていますHttpContext。3.0以降では、IHttpContextAccessor承認ハンドラに挿入して使用します。完全性の例を次に示します。

public class AppKeyAuthorizationHandler : AuthorizationHandler<AppKeyRequirement>
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public AppKeyAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
    {
        var httpContext = httpContextAccessor.HttpContext;
        var query = httpContext.Request.Query;

        if (query.ContainsKey("key") && query.ContainsKey("app"))
        {
            // ...
        }
    }
}

また、登録する必要がありますIHttpContextAccessorConfigureServices

services.AddHttpContextAccessor();

参照カスタムコンポーネントから使用のHttpContextを使用しての詳細についてはIHttpContextAccessor


1
このヒントをありがとう。APIキーがない場合、呼び出しが拒否されるポリシーを作成しようとしています。// Add Key Policy services.AddAuthorization(options => {options.AddPolicy( "AppKey"、policy => policy.Requirements.Add(new AppKeyRequirement())));});をもう使用できませんか?そうでない場合、コントローラのアクションに到達する前にコールを傍受するにはどうすればよいですか?
w2olves

1
はい、それでも以前と同じように機能します。
Kirk Larkin、

コンストラクターはIHttpContextAccessorを期待しています。Startup.csでポリシーを作成するときに、これをどのように渡すことができますか?services.AddAuthorization(options => {options.AddPolicy( "AppKey"、policy => policy.Requirements.Add(new AppKeyRequirement()));}); AppKeyAuthorizationHandlerの新しいデフォルトコンストラクターを作成することもできますが、その場合はhttpContextAccessor.HttpContext; リクエストが来るとnullになります。
w2olves

1
DIを使用してハンドラーを追加すると、ハンドラーのインスタンスが作成され、に渡されますIHttpContextAccessordocsを参照してください。
Kirk Larkin、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.