シングルサインオンの実装を理解するため、IDプロバイダの設定とサービスプロバイダをローカルで動作させるまでの手順をまとめました。
IDプロバイダにはAzureADを、サービスプロバイダにはhttps://github.com/onelogin/python3-saml というライブラリに含まれるpythonで書かれたflaskサーバーのサンプルを動作させます。
事前準備
- https://ngrok.com/ のインストール
-
ngrok http 8000
で起動し、発行された"https"のURLを以降{ngrok_url}として記載
IDプロバイダ(AzureAD)の設定
- Azureポータルを開く(サブスクリプションが作成済みである必要があると思う)
- エンタープライズアプリケーションを開く
- 「新しいアプリケーション」>「独自のアプリケーションの作成」をクリックし「 Integrate any other application you don't find in the gallery (Non-gallery)」を選択してアプリを作成
- 作成したアプリに移動し、「シングルサインオン」を開く。「SAML」を選択して下記を設定。
- 識別子 (エンティティ ID):
{ngrok_url}/metadata/
- 応答 URL:
{ngrok_url}/?acs
- ログアウト URL:
{ngrok_url}/?sls
- 識別子 (エンティティ ID):
- ユーザーとグループを開き、 「ユーザーまたはグループの追加」をクリックして、動作テストしたいユーザーを追加する
サービスプロバイダの設定
- サンプルコードをクローン
git clone git@github.com:onelogin/python3-saml.git
- Azureポータル > エンタープライズアプリケーション > (作成したアプリ)> シングルサインオン に表示されている内容を参考に./demo-flask/saml/settings.jsonを設定する
- sp.entityId:
{ngrok_url}/metadata/
- sp.assertionConsumerService.url:
{ngrok_url}/?acs
- sp.singleLogoutService.url:
{ngrok_url}/?sls
- idp.entityId: XXX(アプリ名)のセットアップ > Azure AD 識別子
- idp.singleSignOnService.url: XXX(アプリ名)のセットアップ > ログイン URL
- idp.singleLogoutService.url: XXX(アプリ名)のセットアップ > ログアウト URL
- idp.x509cert: SAML 署名証明書 > 証明書 (Base64) をダウンロードした中身の文字列(改行やBEGIN CERTIFICATEなどの行は削除)
- sp.entityId:
- https://github.com/onelogin/python3-saml/blob/master/demo-flask/index.py#L26 あたりを下記のように書き換え
'https': 'on',
'http_host': request.host,
'script_name': request.path,
'get_data': request.args.copy(),
'lowercase_urlencoding': True,
'post_data': request.form.copy()
※ ngrokなどのproxyを経由していてもhttps振る舞うよう強制
※ AzureADのSAMLResponseは大文字/小文字の取り扱いが特殊なので、lowercaseに強制
- Mac上での実行に要求されるなライブラリのインストール(必要であれば)
# 参考 https://pypi.org/project/xmlsec/
brew install libxml2 libxmlsec1 pkg-config
- パッケージのインストール
python setup.py install
pip install -r demo-flask/requirements.txt
- サーバーの起動
cd demo-flask
python index.py
動作の確認
ログイン
-
{ngrok_url}
にアクセスしログインする - ユーザーの情報が取得できていることが確認できます
ログアウト
- ログインボタンをクリック
- MSのログアウト画面にリダイレクトされ、続けてSP側に戻ってきて
Successfully logged out
と表示されることが確認できます