ヒント
このコンテンツは、.NET Docs で入手できる、またはオフラインで読み取ることができる無料のダウンロード可能な PDF として入手できる、コンテナー化された .NET アプリケーションの電子ブックである .NET マイクロサービス アーキテクチャからの抜粋です。
マイクロサービスと Web アプリケーションのセキュリティには非常に多くの側面があるため、このトピックでは次のようないくつかの書籍を簡単に取ることができます。 そのため、このセクションでは、認証、承認、およびアプリケーション シークレットに焦点を当てます。
.NET マイクロサービスと Web アプリケーションに認証を実装する
多くの場合、サービスによって公開されるリソースと API は、信頼できる特定のユーザーまたはクライアントに限定する必要があります。 このような API レベルの信頼の決定を行う最初の手順は、認証です。 認証は、ユーザーの ID を確実に検証するプロセスです。
マイクロサービスのシナリオでは、通常、認証は一元的に処理されます。 API ゲートウェイを使用している場合は、図 9-1 に示すように、ゲートウェイを認証することをお勧めします。 この方法を使用する場合は、個々のマイクロサービスがゲートウェイから送信されたかどうかに関係なく、メッセージを認証するための追加のセキュリティが設定されていない限り、個々のマイクロサービスに (API ゲートウェイなしで) 直接到達できないことを確認します。
図 9-1 API ゲートウェイを使用した一元化された認証
API ゲートウェイは、認証を一元化すると、マイクロサービスに要求を転送するときにユーザー情報を追加します。 サービスに直接アクセスできる場合は、Azure Active Directory などの認証サービスまたはセキュリティ トークン サービス (STS) として機能する専用の認証マイクロサービスを使用してユーザーを認証できます。 信頼性の判断は、セキュリティ トークンまたは cookie を使用して、サービス間で共有されます。 (必要に応じて、Cookie 共有を実装することで、ASP.NET Core アプリケーション間でこれらのトークンを 共有できます)。このパターンを図 9-2 に示します。
図 9-2 ID マイクロサービスによる認証。承認トークンを使用して信頼を共有する
マイクロサービスに直接アクセスすると、認証と承認を含む信頼は、マイクロサービス間で共有される専用マイクロサービスによって発行されたセキュリティ トークンによって処理されます。
ASP.NET コア ID を使用して認証する
アプリケーションのユーザーを識別するための ASP.NET Core の主要なメカニズムは 、ASP.NET Core ID メンバーシップ システムです。 ASP.NET Core Identity では、開発者によって構成されたデータ ストアにユーザー情報 (サインイン情報、ロール、要求など) が格納されます。 通常、ASP.NET Core Identity データ ストアは、 Microsoft.AspNetCore.Identity.EntityFrameworkCore
パッケージで提供される Entity Framework ストアです。 ただし、カスタム ストアまたはその他のサード パーティ製パッケージを使用して、Azure Table Storage、CosmosDB、またはその他の場所に ID 情報を格納できます。
ヒント
ASP.NET Core 2.1 以降では 、ASP.NET コア ID がRazor クラス ライブラリとして提供されるため、以前のバージョンの場合と同様に、プロジェクトに必要なコードの多くは表示されません。 ニーズに合わせて ID コードをカスタマイズする方法の詳細については、「 ASP.NET Core プロジェクトでの ID のスキャフォールディング」を参照してください。
次のコードは、ASP.NET Core Web Application MVC プロジェクト テンプレートから取得され、個々のユーザー アカウント認証が選択されています。 Program.cs ファイルで Entity Framework Core を使用してコア ID ASP.NET 構成する方法を示します。
//...
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
//...
ASP.NET Core Identity を構成したら、サービスの app.UseAuthentication()
ファイルの次のコードに示すように、endpoints.MapRazorPages()
と を追加して有効化します。
//...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
//...
Von Bedeutung
上記のコードの行は、ID が正しく機能するために 表示される順序である必要があります 。
ASP.NET Core Identity を使用すると、いくつかのシナリオが可能になります。
UserManager 型 (userManager.CreateAsync) を使用して新しいユーザー情報を作成します。
SignInManager の種類を使用してユーザーを認証します。
signInManager.SignInAsync
を使用して直接サインインするか、ユーザーのパスワードが正しいことを確認してからサインインsignInManager.PasswordSignInAsync
。Cookie に格納された情報(これは ASP.NET Core Identity ミドルウェアによって読み取られます)に基づいてユーザーを識別し、ブラウザーからの後続のリクエストにサインインしたユーザーの ID とクレームが含まれるようにします。
ASP.NET Core Identity では、 2 要素認証もサポートされます。
ローカル ユーザー データ ストアを利用し、(MVC Web アプリケーションの場合と同様に) Cookie を使用して要求間で ID を保持する認証シナリオでは、ASP.NET Core Identity が推奨されるソリューションです。
外部プロバイダーによる認証
ASP.NET Core では、 外部認証プロバイダーを 使用して、ユーザーが OAuth 2.0 フローを使用してサインインできるようにすることもサポートされています。 つまり、ユーザーは Microsoft、Google、Facebook、Twitter などのプロバイダーの既存の認証プロセスを使用してサインインし、それらの ID をアプリケーションの ASP.NET Core ID に関連付けることができます。
外部認証を使用するには、前に説明したように認証ミドルウェアを含めるだけでなく、 app.UseAuthentication()
メソッドを使用して、次の例に示すように外部プロバイダー をProgram.cs に登録する必要もあります。
//...
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication()
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = builder.Configuration["Authentication:Microsoft:ClientId"];
microsoftOptions.ClientSecret = builder.Configuration["Authentication:Microsoft:ClientSecret"];
})
.AddGoogle(googleOptions => { ... })
.AddTwitter(twitterOptions => { ... })
.AddFacebook(facebookOptions => { ... });
//...
一般的な外部認証プロバイダーとそれに関連する NuGet パッケージを次の表に示します。
プロバイダー | パッケージ |
---|---|
マイクロソフト | Microsoft.AspNetCore.Authentication.MicrosoftAccount |
グーグル | Microsoft.AspNetCore.Authentication.Google |
フェイスブック | Microsoft.AspNetCore.Authentication.Facebook |
ツイッター | Microsoft.AspNetCore.Authentication.Twitter |
いずれの場合も、ベンダーに依存し、通常は以下を含むアプリケーション登録手順を完了する必要があります。
- クライアント アプリケーション ID の取得。
- クライアント アプリケーション シークレットの取得。
- 承認ミドルウェアと登録済みプロバイダーによって処理されるリダイレクト URL の構成
- 必要に応じて、シングル サインオン (SSO) シナリオでのサインアウトを適切に処理するようにサインアウト URL を構成します。
外部プロバイダー用にアプリを構成する方法の詳細については、 ASP.NET Core ドキュメントの外部プロバイダー認証を参照してください。
ヒント
すべての詳細は、前述の承認ミドルウェアとサービスによって処理されます。 そのため、図 9-3 に示すように、Visual Studio で ASP.NET Core Web アプリケーション プロジェクトを作成するときに、前述の認証プロバイダーを登録する以外に、 個々のユーザー アカウント 認証オプションを選択するだけで済みます。
図 9-3 Visual Studio 2019 で Web アプリケーション プロジェクトを作成するときに、外部認証を使用するための [個々のユーザー アカウント] オプションを選択します。
前述の外部認証プロバイダーに加えて、より多くの外部認証プロバイダーを使用するためのミドルウェアを提供するサード パーティ製パッケージも利用できます。 一覧については、GitHub の AspNet.Security.OAuth.Providers リポジトリを参照してください。
また、独自の外部認証ミドルウェアを作成して、特別なニーズを解決することもできます。
ベアラー トークンを使用して認証する
ASP.NET コア ID (または ID と外部認証プロバイダー) を使用した認証は、Cookie にユーザー情報を格納することが適切な多くの Web アプリケーション シナリオに適しています。 ただし、他のシナリオでは、Cookie はデータを保持および送信する自然な手段ではありません。
たとえば、シングル ページ アプリケーション (SPA)、ネイティブ クライアント、または他の Web API によってアクセスされる可能性のある RESTful エンドポイントを公開する ASP.NET Core Web API では、通常はベアラー トークン認証を代わりに使用します。 これらの種類のアプリケーションは Cookie では動作しませんが、ベアラー トークンを簡単に取得し、後続の要求の承認ヘッダーに含めることができます。 トークン認証を有効にするために、ASP.NET Core では 、OAuth 2.0 と OpenID Connect を使用するためのいくつかのオプションがサポートされています。
OpenID Connect または OAuth 2.0 ID プロバイダーによる認証
ユーザー情報が Azure Active Directory または OpenID Connect または OAuth 2.0 をサポートする別の ID ソリューションに格納されている場合は、 Microsoft.AspNetCore.Authentication.OpenIdConnect パッケージを使用して OpenID Connect ワークフローを使用して認証できます。 たとえば、eShopOnContainers の Identity.Api マイクロサービスに対して認証を行うために、ASP.NET Core Web アプリケーションでは、Program.csの次の簡略化された例に示すように、そのパッケージのミドルウェアを使用できます。
// Program.cs
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
var callBackUrl = builder.Configuration.GetValue<string>("CallBackUrl");
var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60);
// Add Authentication services
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime))
.AddOpenIdConnect(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = identityUrl.ToString();
options.SignedOutRedirectUri = callBackUrl.ToString();
options.ClientId = useLoadTest ? "mvctest" : "mvc";
options.ClientSecret = "secret";
options.ResponseType = useLoadTest ? "code id_token token" : "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.RequireHttpsMetadata = false;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("orders");
options.Scope.Add("basket");
options.Scope.Add("marketing");
options.Scope.Add("locations");
options.Scope.Add("webshoppingagg");
options.Scope.Add("orders.signalrhub");
});
// Build the app
//…
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
//...
});
このワークフローを使用する場合、すべてのユーザー情報ストレージと認証が ID サービスによって処理されるため、ASP.NET Core Identity ミドルウェアは必要ありません。
ASP.NET Core サービスからセキュリティ トークンを発行する
外部 ID プロバイダーを使用するのではなく、ローカル ASP.NET Core Identity ユーザーに対してセキュリティ トークンを発行する場合は、優れたサード パーティ製ライブラリを利用できます。
IdentityServer4 と OpenIddict は、ASP.NET Core サービスからセキュリティ トークンを発行できるように、ASP.NET Core Identity と簡単に統合できる OpenID Connect プロバイダーです。 IdentityServer4 ドキュメントには、ライブラリを使用するための詳細な手順があります。 ただし、IdentityServer4 を使用してトークンを発行する基本的な手順は次のとおりです。
IdentityServer4 は、ビルダーを呼び出して Program.cs で構成します。Services.AddIdentityServer。
アプリを呼び出します。 Program.cs の UseIdentityServer を使用して、IdentityServer4 をアプリケーションの HTTP 要求処理パイプラインに追加します。 これにより、ライブラリは OpenID Connect および /connect/token などの OAuth2 エンドポイントへの要求を処理できます。
ID サーバーを構成するには、次のデータを設定します。
署名に使用する 資格情報 。
ユーザーがアクセスを要求する可能性がある ID と API リソース :
API リソースは、ユーザーがアクセス トークンを使用してアクセスできる保護されたデータまたは機能を表します。 API リソースの例としては、承認を必要とする Web API (または API のセット) があります。
ID リソースは、ユーザーを識別するためにクライアントに提供される情報 (要求) を表します。 要求には、ユーザー名、電子メール アドレスなどが含まれる場合があります。
トークンを要求するために接続する クライアント 。
ASP.NET Core Identity や代替手段など、ユーザー情報のストレージ メカニズム。
IdentityServer4 で使用するクライアントとリソースを指定すると、メモリ内クライアントまたはリソース ストアを受け取るメソッドに、適切な型の IEnumerable<T> コレクションを渡すことができます。 または、より複雑なシナリオでは、依存関係の挿入を使用してクライアントまたはリソース プロバイダーの種類を指定できます。
カスタム IClientStore 型によって提供されるメモリ内リソースとクライアントを使用するための IdentityServer4 の構成例は、次の例のようになります。
// Program.cs
builder.Services.AddSingleton<IClientStore, CustomClientStore>();
builder.Services.AddIdentityServer()
.AddSigningCredential("CN=sts")
.AddInMemoryApiResources(MyApiResourceProvider.GetAllResources())
.AddAspNetIdentity<ApplicationUser>();
//...
セキュリティ トークンを使用する
OpenID Connect エンドポイントに対する認証または独自のセキュリティ トークンの発行には、いくつかのシナリオが含まれます。 しかし、別のサービスによって提供された有効なセキュリティ トークンを持つユーザーへのアクセスを制限するだけで済むサービスはどうでしょうか。
そのシナリオでは、JWT トークンを処理する認証ミドルウェアは 、Microsoft.AspNetCore.Authentication.JwtBearer パッケージで使用できます。 JWT は "JSON Web トークン" を意味し、セキュリティ要求を通信するための一般的なセキュリティ トークン形式 (RFC 7519 で定義) です。 ミドルウェアを使用してこのようなトークンを使用する方法の簡略化された例は、eShopOnContainers の Ordering.Api マイクロサービスから取得したこのコード フラグメントのようになります。
// Program.cs
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
// Add Authentication services
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = identityUrl;
options.RequireHttpsMetadata = false;
options.Audience = "orders";
});
// Build the app
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
//...
});
この使用法のパラメーターは次のとおりです。
Audience
は、受信トークンの受信者、またはトークンがアクセスを許可するリソースを表します。 このパラメーターで指定された値がトークン内のパラメーターと一致しない場合、トークンは拒否されます。Authority
は、トークン発行認証サーバーのアドレスです。 JWT ベアラー認証ミドルウェアは、この URI を使用して、トークンの署名の検証に使用できる公開キーを取得します。 ミドルウェアは、トークン内のiss
パラメーターがこの URI と一致することも確認します。
RequireHttpsMetadata
別のパラメーターは、テスト目的に役立ちます。証明書がない環境でテストできるように、このパラメーターを false に設定します。 実際のデプロイでは、JWT ベアラー トークンは常に HTTPS 経由でのみ渡す必要があります。
このミドルウェアを配置すると、JWT トークンが承認ヘッダーから自動的に抽出されます。 その後、逆シリアル化され、検証され ( Audience
パラメーターと Authority
パラメーターの値を使用して)、MVC アクションまたは承認フィルターによって後で参照されるユーザー情報として格納されます。
JWT ベアラー認証ミドルウェアでは、ローカル証明書を使用して、機関が使用できない場合にトークンを検証するなど、より高度なシナリオをサポートすることもできます。 このシナリオでは、TokenValidationParameters
オブジェクトでJwtBearerOptions
オブジェクトを指定できます。
その他のリソース
アプリケーション間での Cookie の共有
https://learn.microsoft.com/aspnet/core/security/cookie-sharingID の概要
https://learn.microsoft.com/aspnet/core/security/authentication/identitySMS による 2 要素認証
https://learn.microsoft.com/aspnet/core/security/authentication/2faFacebook、Google、その他の外部プロバイダーを使用した認証の有効化
https://learn.microsoft.com/aspnet/core/security/authentication/social/Michell Anicas。 OAuth 2 の概要
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2AspNet.Security.OAuth.Providers (ASP.NET OAuth プロバイダー用の GitHub リポジトリ)
https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/tree/dev/srcIdentityServer4。 公式ドキュメント
https://identityserver4.readthedocs.io/en/latest/
.NET