こんばんは、cloudpack の @dz_ こと大平かづみです。
Prologue - はじめに
念願だった Bluemix で Azure AD によるシングルサインインを実現する方法を見つけました!青いクラウドをつなぐコラボ!ヽ(≧∀≦)ノ
Bluemix シングルサインインサービス実装時に使った passport モジュールの Strategy として Azure AD サインインを実装したものがあるとの情報を得ました。
それは passport-azure-ad !
わーい!!
と言いながらも、結構つまづいたので、皆さまが少しでも安全に実装できるように、微力ながらメモを残させていただきます。m(_ _)m
※と言いましても、本記事は特に Bluemix に限ったものはなく、一般的な Node.js アプリケーションでの実装です。ご了承くださいませ。
実装の準備
ドキュメント
基本的には以下のドキュメントを参照して進めました。
サンプル
Node.js で passport-azure-ad
を利用するサンプルコードです。今回はこちらを参考に進めました。
参考ドキュメント
上記サンプルを用いた解説の和訳版です。
ベース環境
- Azure Active Directory
- Bluemix
- Node.js
- Express 3.x
- passport
- passport-azure-ad
※上記以外にも適宜利用しています。
実装のポイント
私の奮闘記のすべてを書いてると長いので、私が迷ったポイントに絞って記載します。
ディレクトリ(テナント)の作成
ディレクトリ(テナント)を作成します。Azure管理ポータルで、「新規作成」>「ACTIVE DIRECTORY」>「ディレクトリ」>「カスタム作成」をクリックしてください。
「名前」「ドメイン名」「国/リージョン」を設定します。このとき「ドメイン名」は後の設定で使いますので覚えておいてください。
アプリケーションの追加
アプリケーションの追加をします。作成したディレクトリのアプリケーション一覧を表示し、画面下部の「追加」をクリックしてください。
「組織で開発中のアプリケーションを追加」をクリックしてください。
「名前」を入力し、「種類」は「WEBアプリケーションやWEB API」を選択して次へ進みます。
「サインオンURL」には、サインイン後に戻るURL (上記サンプルを使用した場合は <アプリケーションのURL>/auth/openid/return
) を設定します。「アプリケーションID/URI」には、ディレクトリ(テナント)を作成した際に指定した「ドメイン名」をもとに、 https://<テナント名>.onmicrosoft.com/<任意の文字列(アプリ名など)>
と設定してください。
マルチテナントの有効化
上記ドキュメントに記載されていないのですが、これをしないとサインインループ(後述)になったので、設定しておくと吉です。
Azure管理ポータルで、 Azure AD の「アプリケーション」の「構成」にて設定します。マルチテナントを有効にするには、「アプリケーションID/URI」が正しく設定されている必要があります。(上記参照)
クライアントIDとクライアントシークレット
Azure管理ポータルで、 Azure AD の「アプリケーション」の「構成」にて確認、設定できます。
トラブルシューティング
コールバックURLに戻ってこない
Microsoftの認証画面でサインインのリンクを押すも、またその画面に戻ってしまい、一向に自分のアプリに戻ってこない場合は、「 マルチテナントを有効 」に設定してみてください。設定方法は上記をご参考ください。
アクセストークンの取得に失敗する
InternalOAuthError: failed to obtain access token
このようなエラーになるとき、一つの原因は Microsoftアカウントでログインしようとている 場合です。
この場合、実は内部で以下のエラーによりトークンが取得できていません。
AADSTS90019: No tenant-identifying information found in either the request or implied by any provided credentials
Stackoverflow にも この問題 があがっていました。この回答を参考に説明します。
config.js
の identityMetadata
で設定しているエンドポイントは、"共通" のものであり、Azure AD に登録したユーザーアカウントが「組織アカウント」か「Azure AD アカウント」である場合に利用できます。
...
identityMetadata: 'https://login.microsoftonline.com/common/.well-known/openid-configuration',
...
ただし、Azure AD に登録したユーザーアカウントが「Microsoft アカウント」の場合はこの共通のエンドポイントは使えませんので、アプリケーションのエンドポイントをしっかり設定しなければなりません。
アプリケーションのエンドポイントは、管理ポータルの Azure AD の「アプリケーション」で、画面下部の「エンドポイント」から表示できます。
ここには identityMetadata
に設定できるURLは記載されていないので、以下のようにURLを作って設定してください。
まず、アプリケーションのエンドポイントから任意のエンドポイント、ここでは「OAUTH 2.0 承認エンドポイント」をコピーします。
https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx/oauth2/authorize
これの xxx-xxx-xxx-xxx-xxx
の部分を、identityMetadata
のURLの common
の部分と置き換えてください。
...
// identityMetadata: 'https://login.microsoftonline.com/common/.well-known/openid-configuration',
identityMetadata: 'https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx/.well-known/openid-configuration',
...
これで、Microsoftアカウントを利用したログイン時のアクセストークンが取得できないのエラーは解消すると思われます。
どのURLでもトップページに戻ってしまう
どのURLに遷移しようとしても、トップページ(認証成功後のページ)に戻ってしまうが、ログインはされていない状態の場合、 セッションが効いていない ことが考えられます。
その Node.js のアプリケーションは、 https
でのアクセスでしょうか?
それであれば、セッションに cookie: {httpOnly:false}
とセッションクッキーの設定をすることで、https でのアクセスでもセッションクッキーを利用できます。
...
// app.use(express.session({secret: 'keyboard cat', resave: true, saveUninitialized: false}));
// session に cookie: {httpOnly: false} を追加する
app.use(express.session({secret: 'keyboard cat', resave: true, saveUninitialized: false, cookie: {httpOnly: false}}));
...
セッションの使い方は expressjs/session をご参照ください。なお、Express のセッションは、 3.x と 4.x で変更があるので、別途ご確認ください。
Epilogue - おわりに
大きな課題を一つクリアすることができました!
途中、エラーで困った時に @kazumihirose さんにアドバイスいただきました。ありがとうございます!
シルバーウィーク最終日の今は 3:00 。起きたらお仕事はPHPです。がんばろー!
ちなみに、大変恐縮ですが、この内容をもとに Comm Tech Festival - こみゅぷらす (COMU+) でお話しさせていただく予定です。まだ未熟者ですが、よろしくお願いいたします!
近況
最近
- 第4回 ICTトラブルシューティングコンテストの熱い戦いを拝見させていただきました!
- Check! cmder ~ Windows に Monokai スタイルのコンソールを導入 (実行ポリシーのトラブルシューティング) ←
- Check! Node.js で Azure AD を! ~ passport-azure-ad の導入とトラブルシューティング ←
Bluemix 関連
- Check! Bluemix で Node.js をスピーディーに開発したい!
- Check! DBaaS ってなんだろう? IBM Cloudant を Bluemix で使ってみる。
- Check! Bluemix でユーザー定義の環境変数を利用する (Node.jsによる利用例) ←
Webフレームワーク関連
PHP
Phalcon PHP Framework
- 爆速フレームワーク!! Phalcon PHP Framework
- Meet Volt ! Phalcon 謹製テンプレートエンジン Volt - from 第71回 PHP勉強会
- Meet Phalcon! - Phalcon PHPフレームワークを Nginx on Amazon EC2 にインストール!
CakePHP
その他
Node.js - Express
クラウド・インフラ関連
Amazon Web Services
- Check! はじめての fluentd を Amazon Linux で動かしてみる (ログを PHP から送る)
- Check! はじめての Fluentd 〜 IAMロールで Amazon EC2 と S3 間をセキュアに
- Check! はじめての Zabbix インストール on Debian x Amazon RDS
Azure
- Check! chocolatey で Azure に Windows 作業環境を手早くつくる!
- Check! Azure オートメーション ランブックで OMS Search API を利用する (和訳)
技術ブログ寄稿
cloudpack技術ブログでも記事を書いています。