Xamarinアプリの認証にAzure AD B2Cを使ってみよう

本エントリーは Xamarin Advent Calendar 2016 (その1) 8日目のエントリーです。

Xamarinで開発したアプリは、Azure Mobile Appsと組み合わせることで簡単に認証を組み込めることは各所で説明されている通りです。

Mobile Appsの基盤であるAzure App Serviceでは、執筆時点(2016年12月)では以下のIDプロバイダーがサポートされています(これはEasy Authとも呼ばれているようです)。

  • Azure Active Directory
  • Facebook
  • Google
  • Microsoft
  • Twitter

これだけのIDプロバイダーがサポートされていればだいたいの場面で事足りるのでは?と思うかもしれませんが、例えばソーシャルアカウントを使わずにメールアドレスでサインアップできる認証方法を採用したい場合はどうすれば良いのでしょうか?

Azure Active Directory(AAD)を使えば良いだろうと思うかもしれません。しかし、”通常の”Azure Active Directoryは、特定の組織向けのディレクトリ(メールアドレスの@以降が統一されている)であるため、不特定多数の一般ユーザがサインアップするコンシューマ向けサービスには使えないのです(ここは結構誤解されているようです)。

そこで「Azure Active Directory B2C」ですよ


Azure Active Directory B2Cでできること

名前こそAzure Active Directoryですが、できることは組織用のAzure Active Directoryとは少し異なります。

サービス毎にIDをストアできるIDプロバイダとしての基盤は当然ながら、セルフサインアップ(これが重要!)、サインイン、パスワードリセット、マルチファクター認証など、コンシューマ向けのIDプロバイダーに必要な機能や画面が最初から揃っているという便利なサービスです。

例えば、Xamarinで実装されたモバイルアプリからAzure Active Directory B2Cで認証されたAPIにアクセスすると、以下のような認証画面(サインアップも可能)が出るようになります。

Azure Active Directory B2Cで嬉しいことは、まず何よりも認証基盤を自作しなくて良いこと。セキュリティ周りの自作や中途半端な知識に基づいた実装は無駄で危険も多いので、ここは重要なポイントではないでしょうか。

なお、Azure Active Directory B2Cはまだ新しいサービスのため、執筆時点(2016年12月)では北米リージョンにしかデプロイできないなどいくつか制約事項があります。制約事項の詳細は以下の公式ドキュメントを確認するようにして下さい。

では、XamarinでAAD B2C認証できるようになるまでをざっと流していきます。


Azure Active Directory B2Cディレクトリを準備する

まず認証の基盤となるAzure Active Directory B2C(以降、AAD B2C)ディレクトリを作成します。作成手順は通常の組織向けActive Directoryと異なり、対象サービス(アプリ)毎にディレクトリを作成します。サービス専用のユーザストアが出来上がるイメージです。

B2Cディレクトリの作成

Azure AD B2C用に新規のディレクトリ(テナント)を作成します。なお、B2C用のディレクトリは執筆時点(2016年12月)では、クラシックポータル(manage.windowsazure.comの方)での操作が必要になります。

ディレクトリ追加時に、[これは B2C ディレクトリです。] にチェックを入れます。また、現時点ではリージョンには米国を選択する必要があるようです。

B2C専用サブスクリプションの割り当て

サブスクリプションをAzure AD B2Cディレクトリに割り当てる必要があります。しかし、サブスクリプションの新規作成時に最初からB2Cディレクトリに関連づけることができないようなので(何か方法があればどなたか教えて下さい)、以下のように別のディレクトリ配下で作成しておいたサブスクリプションをB2Cディレクトリに移動することで解決しました。この操作もクラシックポータル限定になります。

[設定]-[サブスクリプション]-[ディレクトリの編集]で、B2C用に使いたいサブスクリプションをB2Cディレクトリに関連づけます。


B2C用Mobile Appsの作成

通常のポータル(portal.azure.comの方)に戻り、作成したB2C用のディレクトリに選択し直してから、Xamarinから利用するバックエンドアプリケーションをAzure Mobile Appsで作成します。Mobile AppsはQuick Startで作成しておくのが無難です。

B2Cディレクトリへのアプリ登録

[Azure AD B2C]の設定画面に移動し、作成したMobile AppsをB2Cディレクトリで使えるアプリとして登録します。

ReplyURLは、Mobile AppのURLに/.auth/login/aad/callbackを加えた文字列とします(httpsへの変更も忘れずに)。それ以外はスクリーンショットを参考にして下さい。

登録されたアプリの[Application ID](クライアントID)は後で使うのでメモしておくようにします。

サインアップ/サインインポリシーの作成

次にサインアップ/サインインポリシーを作成します。とりあえずこの例では、入力項目はメールアドレスのみにしておきます(名前とか住所とかいろいろ登録可能項目が用意されています)。また、サインイン/サインアップUIの入力項目やデザインもここからカスタマイズが可能です。

ここで発行された[Metadata Endpoint for this policy]の文字列は後で使うのでメモしておきます。


Azure Mobile Appsに認証を組み込む

次に、Xamarinアプリのバックエンドサービス(mBaaS)となるAzure Mobile Apps(App Service)にAzure AD B2Cの認証を組み込んでいきます。

認証プロバイダー設定

[App Service]-[対象のMobile Apps]の設定で、[認証/承認]を以下のように設定します。

  • App Service 認証: オン
  • 認証プロバイダー: Azure Active Directory
  • 管理モード: オン
  • クライアントID: Azure AD B2Cで発行したApplication ID(呼び方が違うので注意)
  • 発行者のURL: サインアップ/サインインポリシーで発行された[Metadata Endpoint for this policy]文字列(長いので注意)

サーバー機能での認証有効化

Mobile Appsが提供する各機能で認証を有効にします。提供しているバックエンドサービスによってそれぞれ方法が異なります。

Easy TablesやEasy APIを使っている場合は、以下のようにパーミッションを設定するだけで認証が有効になります。

C#でAPIを作成している場合は、コントローラに[Authorize]属性を付けるだけです。


Xamarinで作成するクライアントアプリに認証機能を組み込む

ようやく、Xamarin側の設定に入ります(Xamarin Advent Calendar向けなのに、半分以上がAzureに関する内容だったことにここで気づきました・・)。

Xamarinアプリは、Azure Mobile Appsのクイックスタート機能からダウンロードしたXamarin.Formsアプリを前提に進めていきます。

PCL

PCLにはIAuthenticateインタフェースを用意し、MobileServiceClientのLoginAsync拡張メソッドを各プラットフォームに実装します。よりエレガントに実装する方法などはGithubにて大募集中です。

Xamarin.Formsアプリなので、認証画面に遷移するためのイベントハンドラーを仕込んでおくなどの実装もやっておきます。認証画面のそのものは、Azure AD B2CのWeb画面がWebViewで表示されるので実装は不要です。

イベントハンドラーの実装例はGithubにどうぞ(ただし、リファクタリングの余地大です)。

プラットフォーム固有実装(iOS, Android)

iOS側及びAndroidでのIAuthenticateインターフェイスを実装する方法は以下を参考にして下さい。こちらもエレガントに実装する方法はGithubにて絶賛募集中!

これで実際に認証画面が表示されるようになりました(左: サインアップ、右: サインイン)。あとは、サインアップすれば登録したメールアドレスでいつでもサインインできます。

ソースコードは、Githubに公開していますので、Xamarinでデバッグができる環境の方は、実際に動かしてAzure AD B2Cにサインアップやサインインを試してみて下さい!B2Cディレクトリは絶賛開放中です。


まとめ

今回の例では、Azure Mobile App側にB2Cの認証を紐付け、サーバ機能が呼ばれた時に認証が求められるモデル(Server-managedモデル)を紹介しましたが、Xamarinクライアントに直接B2C認証を組み込むこともできるので(Client-managedモデル)、それは別の機会に紹介したいと思います。

記事としてはだいぶ長くなってしまいましたが、これだけの手順でユーザ認証基盤も認証対応クライアントアプリも出来てしまうというのはちょっと驚きでした。いい時代になりましたね。