Azure AD B2C学習メモ
Tags: azure, csharp
Published: 2024-01-06 07:54:40

---
title: Azure AD B2C学習メモ
published: true
description: 
tags: azure,csharp
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-01-06 06:32 +0000
---

## モチベーション
Auth0、Firebase Authenticationなど、Webサービスの認証を、独立した外部サーバーにするID as a Serviceですが、
Azureにも同じようなものが存在していて、それがAzure AD B2Cです。

セキュリティ対策が大変なユーザー認証周りを既存のサービスやライブラリに任せることができたり、
ソーシャルログインやMFAなどの対応が楽になるというメリットがある一方、
使い方を把握する必要があります。

参考になったリンクや情報をメモしておきます。

## 想定アーキテクチャ
今回想定するアーキテクチャはシンプルなSPAとバックエンドAPIの構成になります。

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbq6osxweamdyxnkfhia.png)

## ライブラリとドキュメントの場所

### ADB2Cテナントの作成
AADB2Cでは、認証サーバーをテナントという概念で管理していて、まずはテナントを作成する必要があります。
テナントは下記ドキュメントで作成できます。

https://learn.microsoft.com/ja-jp/azure/active-directory-b2c/tutorial-create-tenant

アプリを作るとき、プラットフォームを聞かれますが、spaを選択します。

テナントを作ったら、ポータルから以下のconfig情報を頑張って探してきます。

```
  "AzureAdB2C": {
    "Instance": "https://{テナント名}.b2clogin.com",
    "ClientId": "{ポータルに記載されているClientId}",
    "Domain": "{テナント名}.onmicrosoft.com",
    "SignUpSignInPolicyId": "{サインインサインアップのポリシーID (B2C_1_*)}",
    "AllowWebApiToBeAuthorizedByACL": true
  },
```

### SPAとAADB2Cとの接続
AADB2CはOpenIdConnectというプロトコルで通信を行うので、フロントエンドJavaScriptからOpenIdConnectを使う必要があります。

しかし、AADB2Cに最適なライブラリ([msal-browser](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser))が公式から提供されているのでこれを使います。
https://learn.microsoft.com/ja-jp/azure/active-directory-b2c/configure-authentication-sample-spa-app

githubにも使い方のmarkdownがあるので、これを参考にするのも良さそうです。
https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser#msal-basics

MSAL-browserはPublicClientApplicationクラスにconfigを渡すのですが、
先程テナントを作るときに作ったconfigをうまく割り当てます

```js
new PublicClientApplication({
    auth: {
      clientId: aadb2cOption.ClientId,
      redirectUri: `${appConfig.FrontendUrl}/auth-redirect`,
      navigateToLoginRequestUrl: false,
      authority: `${aadb2cOption.Instance}/${aadb2cOption.Domain}/${aadb2cOption.SignUpSignInPolicyId}`,
      knownAuthorities: [aadb2cOption.Instance]
    },
    cache: {
      cacheLocation: 'sessionStorage', // This configures where your cache will be stored
      storeAuthStateInCookie: false // Set this to "true" if you are having issues on IE11 or Edge
    }
  })
```

### ASP.NET APIとAADB2Cを接続する
ASP.NETのバックエンドAPIと接続するには、下記ドキュメントが良さそうです。
https://learn.microsoft.com/ja-jp/azure/active-directory-b2c/enable-authentication-web-api?tabs=csharpclient

ASP.NETとAADB2Cを接続するには、 `Microsoft.Identity.Web` というライブラリを使います。

`Microsoft.Identity.Web.UI` というライブラリもありますが、これはControllerが自動で生えるので今回は使いません。

ServiceCollectionを作るときに、AddMicrosoftIdentityWebApiというのをつけます。
これでAuthorize属性がついたエンドポイントは、tokenの検証が入ります。
```
builder.Services.AddAuthentication()
            .AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAdB2C");
```

`AddMicrosoftIdentityWebApp` もありますが、これはバックエンドがAPI用ではなく、普通のASP.NET MVCのrazor page用 (cookie認証) での使用が本来の用途のようなので今回は使用しません。

### API通信をする
あとはMSAL-browserのドキュメントに則って通信をすれば、良いです。
せっかくなのでメモ書きを残しておきます。

ログインをするには、loginRedirectを使います。

```
await msalClient.initialize();
await auth.client.value.loginRedirect({
      scopes: ['openid']
})
```
するとAADB2Cのログイン画面にリダイレクトされ、認証が成功すると、redirect-urlにリダイレクトが返ってきます。

リダイレクトが返ってきたら、handleRedirectPromise();を実行して、authorization codeを受け取ります。
さらにその中でtoken endpointにリクエストを送り、id_tokenとaccess_tokenを取得します。
```
await msalClient.handleRedirectPromise();
```

最後に、取得したaccess_tokenをAuthorization Headerに入れて、ASP.NETのAPIを呼び出せば成功するはずです。

## 雑メモ
### AADB2CのリダイレクトURLが変わらない
どうやら反映に1時間ほどかかるようです。すぐに反映したい場合はテナント内のアプリケーションを作り直すとよさそうです。

https://learn.microsoft.com/en-us/answers/questions/1181295/azure-b2c-redirect-url-takes-around-1h-before-take