目次
アプリに認証機能を実装するためにAzure AD B2Cを使った備忘録。AzureWebServiceは既に作成済みという前提で解説します。
登録したユーザーのみが開発したWebServiceにアクセスでき、そのWebServiceからユーザーの名前の変更なども可能にする要件を満たすまでの備忘録
Azure AD B2C の作成
詳しい手順については下記サイトが一番参考になる。Azure Poralの使い方に慣れていれば詰まることはないと思います。
Azure Active Directory B2C でユーザー認証を超簡単に実装しよう
テナントとディレクトリの切り替え
Azure B2C を作成すると、アクセスできるユーザー一覧が作成されます。これはディレクトリと呼ばれるものでAzureにアクセスできる組織のユーザー一覧とは別のディレクトリとなります。現在のディレクトリは下記画像の右上で確認できます。Azure B2Cのディレクトリだとサブスクリプションが存在していない表記になりAppServiceの設定変更ができなくなったので、最初は私は自分の権限が削除されたのではないかと勘違いしました。歯車マークから必要に応じてディレクトリに選択してください。
後述のシークレットIDの登録やAPI公開などはB2Cのディレクトリから作成する必要がある。はじめてAzure AD B2Cを使う人はかなり戸惑うと思う。
ユーザーフローの作成
簡単にログイン画面を作成できます。サインイン、サインアップもしくはその両方など要件に応じて作成可能。
よくあるパスワード忘れページもチェックボックスを入れるだけで作成できます。
既定だと英語表記なので言語のカスタマイズを有効化して日本語に変更します。
アプリの登録
ログイン画面と開発中のAppServiceを紐づける作業をします。
新規作成
B2Cのディレクトリから「アプリの登録」を選択して「新規登録」
リダイレクトURLの値は自分の場合は下記3つ+1つ(ローカル用のテスト)で必要でした。
- https://{AzureAppServiceの名称}.azurewebsites.net/.auth/login/{OpenIdプロバイダーの名称}/callback
- https://{AzureAppServiceの名称}.azurewebsites.net/signin-oidc
- https://login.microsoftonline.com/common/oauth2/v2.0/token
- https://localhost:44321/signin–oidc
フロントチャネルのログアウト URLはhttps://{AzureAppServiceの名称}azurewebsites.net/.auth/logoutに設定して下さい。ここにアクセスするとB2Cからログアウトできるのでアプリ側でリダイレクトする仕組みをあとで作成するのに必要です。
証明書とシークレット
トークンの要求時にWebAppServiceが自身のIDを証明するためにクライアントシークレットを作成します。作成時にしか値が表示されないのでメモします。後述のIDプロバイダーの作成で必要となります。
設定項目
上記に加えてアプリケーション(クライアントID)とディレクトリ(テナント)などもIDプロバイダーの作成で必要なので一緒にメモします。
アプリ登録から下記の情報を収集しておきます。
- アプリケーション (クライアント)
- Azure AD B2C OpenID Connect メタデータ ドキュメント
- ユーザーフローの名前
- ディレクトリ(テナントID)
ディレクトリ(テナントID)はIDプロバイダーの作成では使いませんが後でサーバサイドの設定で使用するのでこれもメモします。
OpenIDプロバイダーの作成
Azure AD B2Cを作成する前にまずAppServiceにてIDプロバイダーを作成します。今回はOpenIDプロバイダーを作成します。
事前にメモした値を入力してIDプロバイダーを追加します。
- OpenIDプロバイダー・・適当に<AppService名>OpenID
- メタデータURL・・・Azure AD B2C OpenID Connect メタデータ ドキュメント<policy-name>にはユーザーフローの名前を入力します。
- クライアントID・・・アプリ登録のアプリケーション(クライアントID)
- クライアントシークレット・・・アプリ登録のシークレット
登録後は編集から認証されていない要求を適切なものに設定しておきます
許可される外部リダイレクトURLを設定します。
- https://{Webサービス名}.azurewebsites.net/.auth/login/{OpenIDの名称}/callback
- https://{Webサービス名}.azurewebsites.net/signin-oidc
- https://{Webサービス名}.b2clogin.com/{Webサービス名}.onmicrosoft.com/b2c_1_signin/discovery/v2.0/keys
- https://login.microsoftonline.com/common/oauth2/v2.0/token
- https://{Webサービス名}.b2clogin.com/{Webサービス名}.onmicrosoft.com/{ユーザーフロー名}/discovery/v2.0/keys
この一覧ですがメタデータURLにアクセスして取得できるJSONに記載されているURLを入力しています。
https://{Webサービス名}.b2clogin.com/{Webサービス名}.onmicrosoft.com/{ユーザーフロー名}/v2.0/.well-known/openid-configuration
サーバーサイドの作成
自分のWebServiceとAzure AD B2Cにアクセスできるように調整します。ユーザー情報を変更するにはMicrosoft.Graphも必要なのでこちらも解説もします。
Nugetの導入
下記ライブラリが必要となります。
- Azure.Identity
- Microsoft.Graph
- Microsoft.Identity.Client
- Microsoft.Extensions.Configuration.Abstraction
appsettings.jsonの修正
ConfigureOptionsの使い方については割愛
{
:
"AzureAdB2C": {
"Instance": "https://<B2Cのドメイン>.b2clogin.com",
"Domain": "<B2Cのドメイン>.onmicrosoft.com",
"TenantId": "<ディレクトリID>",
"ClientId": "a07106be-48b5-4b26-827d-536d1f01771b",
"ClientSecret": "<アプリ登録のシークレット>",
"SignedOutCallbackPath": "/signout/B2C_1_signin",
"SignUpSignInPolicyId": "B2C_1_signin"
},
:
}
Program.csの修正
builder.Services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
// Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
builder.Services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
// Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, Constants.AzureAdB2C);
builder.Services.AddOptions();
builder.Services.Configure<OpenIdConnectOptions>(builder.Configuration.GetSection("AzureAdB2C"));
var app = builder.Build();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
Microsoft Graph APIのアクセス許可
アプリの登録からAPIの公開設定を調整します。
アクセス許可の追加を押すと右ペインに下記のようなページが表示されるはず
あとはアプリケーションの許可から下記のアクセスを許可します。
- Directory,ReadWrite.All
- User.Invite.All
- User.ReadWrite.All
追加したアクセス許可の状態が✓マークでない場合は「管理者の同期を与えます」を実行して設定は完了。
サンプルコード
コードの作成は下記サイトが参考になりました。
C# から Microsoft Graph API を利用して Azure AD B2C にユーザーを登録するまで
詰まったところはMicrosoft.Graph.Authが非推奨になってサンプルコードを修正する必要が出た点。代わりにAzure.Identityを使います。参照先のサイトでClientCredentialProviderクラスを使っていたところを下記のようなコードに修正します。
ちなみにscopeは”https://graph.microsoft.com/.default”です。アプリケーション登録で作成されたurlではないです。
var graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await client
.AcquireTokenForClient(scopes)
.ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
サインアウト
App Service Authentication からログアウトした際に Azure AD B2C からもログアウトしないとダメみたい
https://{servicename}.azurewebsites.net/.auth/logout
にアクセスする
余談
IDプロバイダーの許可される外部リダイレクトURLとアプリ登録のリダイレクトURLは設定してから反映に時間がかかるので注意が必要です。The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.というエラーがでた場合は反映待ちであることが多いので気長に待ちましょう。
参考文献
Azure Static Web Apps を Azure AD B2C で認証
Azure Active Directory B2C のサンプル コード
チュートリアル:Azure Active Directory B2C テナントの作成
チュートリアル:Azure Active Directory B2C に Web アプリケーションを登録する
チュートリアル: Azure Active Directory B2C でユーザー フローとカスタム ポリシーを作成する