しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure AD B2C が MSAL.js v2 に対応したようなので試した

MSAL.js v2 の RTM 時には Azure AD B2C は CORS 周りの機能がデプロイされていないため非対応になっていましたが、既存のテナントへの CORS 対応のデプロイが進められているようです。自分のテナントで使えるようになっていたので試しました。

MSAL.js には種類がありますが、今回試しているのは MSAL Browser と呼ばれるブラウザで動くやつです。

これまで MSAL.js と SPA の組み合わせでは Implicit Flow のみ利用可能でしたが、最近は Implicit Flow が非推奨になっているので Authorization Code Flow + PKCE を使うようになっています。

Azure AD B2C の設定画面でも SPA を追加すると、その旨が記載されています。

f:id:shiba-yan:20200905222023p:plain

Authorization Code Flow の場合は CORS に対応する必要があるので、Azure B2C 側の対応待ちという話でした。この辺りに関しては近日中に公式リリースが出る気がします。

とりあえずミニマムなコードで MSAL.js v2 と Azure AD B2C の組み合わせを試します。

流れとしては PublicClientApplication を作成して loginPopup を実行するとポップアップ内でログインが行われます。await でシームレスに扱えるので便利です。

<!DOCTYPE html>
<html>
<head>
  <script src="https://alcdn.msauth.net/browser/2.1.0/js/msal-browser.min.js" integrity="sha384-EmYPwkfj+VVmL1brMS1h6jUztl4QMS8Qq8xlZNgIT/luzg7MAzDVrRa2JxbNmk/e" crossorigin="anonymous"></script>
</head>
<body>
  <script>
    const msalConfig = {
      auth: {
        clientId: "CLIENT_ID",
        authority: "https://yourtenant.b2clogin.com/yourtenant.onmicrosoft.com/B2C_1_SignUp_SignIn_v2",
        knownAuthorities: ["yourtenant.b2clogin.com"]
      }
    }

    const loginRequest = {
      scopes: ["openid", "offline_access"]
    }

    const msalInstance = new msal.PublicClientApplication(msalConfig);

    async function loginAsync() {
      try {
        const loginResponse = await msalInstance.loginPopup(loginRequest);

        console.log(loginResponse);
      } catch (err) {
        console.error(err);
      }
    }

    loginAsync();
  </script>
</body>
</html>

設定としてはいつも通りの clientIdauthority として User Flow 名付きの URL、そして knownAuthorities が必要です。具体的な値はサンプルコードを見てもらった方が早いです。

このサンプルではトークンのキャッシュを行っていないので毎回ログインされてしまいますが、実際のアプリケーションではトークンの有効期限が切れるまではキャッシュを使うのが基本的な流れです。今回は MSAL.js なら簡単に実装出来るのと、B2C に関係ない部分なので省略します。

適当にホストしてブラウザからアクセスすると、B2C のログイン画面がポップアップ表示されます。

f:id:shiba-yan:20200906003724p:plain

ユーザー登録、もしくはログインを行うと Authorization Code を使ってトークンを取りに行きますが、この時の Pre-flight request で CORS 対応されているのが確認できます。

以前は Pre-flight でエラーになっていたので、トークン取得まで進めませんでした。

f:id:shiba-yan:20200906014628p:plain

もちろん CORS に対応しているので、その後のトークン取得も問題なく行われます。ちゃんと id_tokenrefresh_token などが返ってきていることが確認できます。

f:id:shiba-yan:20200905233002p:plain

実際の loginPopup の戻り値ではクレームがデコードされた状態で入ってくるので、アプリケーションから簡単に使えるのはこれまで通りです。

SPA に MSAL.js v2 を組み込むことで、Azure AD B2C の利用がセキュアかつシンプルになるので良い感じです。ちゃんと PKCE に対応しているのも良いです。