web-dev-qa-db-ja.com

Dotnet Core 2.0認証の複数スキーマID CookieとJWT

Dotnet core 1.1 aspでは、次の操作を行うことで、IDミドルウェアに続いてjwtミドルウェアを構成および使用できました。

  app.UseIdentity();
  app.UseJwtBearerAuthentication(new JwtBearerOptions() {});

これは、ミドルウェアを次のように実装するという点で変更されました。

   app.UseAuthentication();

設定の構成は、Startup.csのConfigureServicesセクションを介して行われます。

移行ドキュメントには、認可スキーマの使用に関するいくつかの参照があります。

https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x#authentication-middleware-and-services

2.0プロジェクトでは、認証はサービスを介して構成されます。各認証スキームは、Startup.csのConfigureServicesメソッドに登録されます。 UseIdentityメソッドはUseAuthenticationに置き換えられました。

さらに、以下への参照があります。

デフォルトの認証スキームの設定

1.xでは、AutomaticAuthenticateプロパティとAutomaticChallengeプロパティは、単一の認証スキームで設定することを目的としていました。これを実施する良い方法はありませんでした。

2.0では、これら2つのプロパティは個々のAuthenticationOptionsインスタンスのフラグとして削除され、ベースAuthenticationOptionsクラスに移動しました。プロパティは、Startup.csのConfigureServicesメソッド内のAddAuthenticationメソッド呼び出しで構成できます。

または、AddAuthenticationメソッドのオーバーロードバージョンを使用して、複数のプロパティを設定します。次のオーバーロードメソッドの例では、デフォルトのスキームはCookieAuthenticationDefaults.AuthenticationSchemeに設定されています。あるいは、認証スキームは、個々の[Authorize]属性または承認ポリシー内で指定できます。

Dotnet core 2.0で複数の認証スキーマを使用することはまだ可能ですか? JWT構成( "Bearer"スキーマ)を尊重するポリシーを取得できず、両方が構成された状態でIdentityのみが現在機能しています。複数の認証スキーマのサンプルが見つかりません。

編集:

私はドキュメントを読み直しましたが、今では次のことを理解しています

app.UseAuthentication()

デフォルトのスキーマに対する自動認証を追加します。 Identityはデフォルトのスキーマを設定します。

Startup.cs Configureで次の操作を行うことで、新しいAPIに対してハックが働いているように見える問題を回避しました。

    app.UseAuthentication();
    app.Use(async (context, next) =>
    {
        if (!context.User.Identity.IsAuthenticated)
        {
            var result = await context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
            if (result?.Principal != null)
            {
                context.User = result.Principal;
            }
        }

        await next.Invoke();
    });

これはこれを行う正しい方法ですか、またはIAuthenticationSchemeProviderのカスタム実装のためにフレームワーク、DIおよびインターフェースを利用する必要がありますか?

編集-実装の詳細と場所。

JWT Configはここにあります。承認された認証スキーマを含む承認を定義するポリシーを使用しています。

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Management/Startup.cs

カスタムミドルウェアはまだ実装されています。認証コントローラは次のとおりです。

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/AuthController.cs

アプリによって生成されたAPIキーを使用して、データへの読み取り専用アクセスを取得します。ここでポリシーを利用するコントローラーの実装を見つけることができます:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/SitemapController.cs

SQL Serverを指すようにDB接続文字列を変更し、アプリケーションを実行します。 DBを自動的に移行し、管理ユーザーを構成します([email protected]!)。次に、メニューバーの[設定]タブに移動し、[JWT ReadOnly APIキー設定の構成]をクリックしてキーを取得します。郵便配達員で、新しいタブを設定し、次のアドレスでPOSTに設定してjwtトークンを取得します。

http:// localhost:5000/api/auth/readonly-token

ヘッダーを指定します:Content-Type:application/json

本体を供給します。

{
    "apiKey": "the api token from the previous step"
}

応答内のトークンをコピーしてから、postmanで次を使用します。

http:// localhost:5000/api/sitemap/flat

Authorization: "bearer - The token you received in the previous request"

カスタムミドルウェアにより、最初は動作します。上記のコードをコメント化して再試行すると、401が表示されます。

以下の編集-@ DonnyTianの答えは、彼のコメントで私の解決策をカバーしています。私が抱えていた問題は、UseMvcにデフォルトポリシーを設定することでしたが、スキーマを提供していませんでした:

    services.AddMvc(config =>
    {
        var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(defaultPolicy));
        config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        config.Filters.Add(new ValidateModelAttribute());
    });

アドバイスに従って、これはカスタムミドルウェアなしで機能します。

28
didiHamman

Asp.Net Core 2.0は間違いなく複数の認証スキームをサポートしています。認証ミドルウェアを使用したハッキン​​グではなく、Authorize属性でスキーマを指定することができます。

_[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
_

試してみたところ、うまくいきました。以下のようにIdentityとJWTの両方を追加したと仮定します。

_services.AddIdentity<ApplicationUser, ApplicationRole>()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
_

AddIdentity()は既にデフォルトのスキーマとしてCookie認証を設定しているため、コントローラーのAuthorize属性でスキーマを指定する必要があります。現時点では、AddIdentity()によって設定されたデフォルトのスキーマを上書きする方法がわかりません。または、それを行わないほうがよいでしょう。

回避策は、Authorizeから派生し、デフォルトのスキーマとしてBearerを持つ新しいクラス(JwtAuthorizeと呼ぶことができます)を作成することです。そのため、毎回指定する必要はありません。時間。

[〜#〜] update [〜#〜]

Identityのデフォルト認証スキームをオーバーライドする方法を見つけました!

以下の行の代わりに:

_services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
_

以下のオーバーロードを使用して、デフォルトのスキーマを設定します。

_services.AddAuthentication(option =>
                {
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>....
_

PDATE 2コメントで述べたように、IdentityとJWTの両方の認証を有効にすることができます。 [Authorize(AuthenticationSchemes = "Identity.Application" + "," + JwtBearerDefaults.AuthenticationScheme)]

22
DonnyTian

この質問は、.Net Core 2.0 WebアプリケーションでID認証とBearer認証を組み合わせるという(同様の)問題を解決するために使用しました。重要なのは、次のコードにnew[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationSchemeを追加する必要があることです。

services.AddMvc(config =>
    {
        var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(defaultPolicy));
        config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        config.Filters.Add(new ValidateModelAttribute());
    });

[〜#〜] and [〜#〜]

デフォルトの認証オプションを追加します。

services.AddAuthentication(option =>
                {
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>....

この質問に基づいた最初のソリューションでは、コードの両方の変更が必要であることに気付きませんでした。うまくいけば、私が無駄にした時間を誰かに節約できます:)

14
MartinH

ここでケビンリッチが言っていることに基づいて http://www.whoiskevinrich.com/configuring-asp-net-core-2-0-authentication

デフォルトの認証方法としてjwtを設定できました。

        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
        })

これをテストし、donnytianの投稿で言及されているauthorize属性から(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)を削除することができました。

1
John

Sean Wildermuthには、Cookieとjwtの両方を有効にするブログ投稿があります。 https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2

彼は次のように連鎖します。

services.AddAuthentication()
  .AddCookie(cfg => cfg.SlidingExpiration = true)
  .AddJwtBearer(cfg =>
  {
    cfg.RequireHttpsMetadata = false;
    cfg.SaveToken = true;

    cfg.TokenValidationParameters = new TokenValidationParameters()
    {
      ValidIssuer = Configuration["Tokens:Issuer"],
      ValidAudience = Configuration["Tokens:Issuer"],
      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
    };

  });
0
Guerrilla