#mynavi(Azureメモ) #setlinebreak(on); * 概要 [#dadf4db4] #html(<div class="pl10">) Azure App Service で配備した Grafana でAD(Active Directory)認証を行う手順を記載する。 尚、認証以外の部分は、[[Azure App Service に Grafana をデプロイ]] をベースにしている為、詳細はそちらを参照。 #html(</div>) * 目次 [#g9c9f576] #contents - 関連 -- [[Azureメモ]] -- [[Azure App Service に Grafana をデプロイ]] -- [[Azure VM上にGrafanaをデプロイ]] - 参考 -- [[Microsoft ID プラットフォーム を使用したアプリのサインイン フロー>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/app-sign-in-flow]] -- [[Microsoft ID プラットフォームを使用した認証と承認>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/authentication-vs-authorization#authentication-and-authorization-using-microsoft-identity-platform]] -- [[Microsoft ID プラットフォームと OAuth 2.0 認証コード フロー>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow]] -- [[認証コード フローと暗黙的なフロー(Web Apps)>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-app-types#web-apps]] -- [[Azure AD OAuth2 authentication>https://grafana.com/docs/grafana/latest/auth/azuread/]] -- [[Microsoft ID プラットフォームと暗黙的な許可のフロー (暗黙的な許可フローの有効有効化)>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-implicit-grant-flow#send-the-sign-in-request]] -- [[Azure Active Directory を使ってアプリケーションに対するグループ要求を構成する>https://docs.microsoft.com/ja-jp/azure/active-directory/hybrid/how-to-connect-fed-group-claims#configure-the-azure-ad-application-registration-for-group-attributes]] -- [[アプリケーションにアプリ ロールを追加してトークンで受け取る>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps]] * ADアプリ 及び シークレットの作成 [#m5cf0c30] #html(<div class="pl10">) シークレットの作成は App Service アプリを登録してから、そのアプリのシークレットとして登録しても良いが、 認証のベースとなるアプリ 及び シークレット は、以下の理由で別アプリとして先に作成しておく。 - 既に認証情報を持つアプリが存在するケースへの対応( 複数アプリ間の SSO まで考慮 )&br; ※ここで登録しているアプリは、先行でリリース済みの別アプリとして考える。 - App Service の作成時にOAuth系の環境変数の設定まで行いたい為。 - 開発段階ではシークレットが、特定のアプリに依存していない方が削除、作り直しが行いやすい。 #html(){{ <style> .images div { vertical-align: top; margin-right: 20px; } .images img { border: 1px solid #333; } </style> }} ** ADアプリの登録 [#x0578f87] #html(<div class="pl10">) #html(<div class="images"><div class="ib">) [Active Directory] を選択 &ref(create_secret1-1.png,nolink); #html(</div><div class="ib">) [アプリの登録] を選択 &ref(create_secret1-2.png,nolink); #html(</div><div class="ib">) [新規登録] を選択 &ref(create_secret1-3.png,nolink); #html(</div><div class="ib">) アプリケーション名を入力して登録 &ref(create_secret1-4.png,nolink); #html(</div><div class="ib">) クライアントID 及び テナントID を確認しておく &ref(create_secret1-5.png,nolink); #html(</div></div>) #html(</div>) ** クライアントシークレットの作成 [#ae9c173b] #html(<div class="pl10">) #html(<div class="images"><div class="ib">) [証明書とシークレット] → [新しいクライアントシークレット] を選択 &ref(create_secret1-6.png,nolink); #html(</div><div class="ib">) 説明を入力して [追加] &ref(create_secret1-7.png,nolink); #html(</div><div class="ib">) 登録したクライアントシークレットを確認しておく。(追加直後しか確認できないので注意) &ref(create_secret1-8.png,nolink); #html(</div></div>) #html(</div>) ** 認証設定 [#nb493ae5] #html(<div class="pl10">) #html(<div class="images"><div class="ib">) [認証] → [プラットフォームの追加] &ref(create_secret1-9.png,nolink); #html(</div><div class="">) #html(<div class="ib">) リダイレクトURI 等を登録する。 &ref(create_secret1-10b.png,nolink); #html(</div><div class="ib">) | 項目 | 設定値 |h | リダイレクトURI | https://Grafanaアプリケーション名.azurewebsites.net/login/azuread | | 〃(2つ目)| https://Grafanaアプリケーション名.azurewebsites.net/.auth/login | | 〃(2つ目)| https://Grafanaアプリケーション名.azurewebsites.net/.auth/login/aad/callback | | 暗黙的な許可フロー | シークレットを 他の Service App と共用する場合は2つともチェックを入れておく | ※ Grafanaアプリケーション名は 後述の 0_env.sh の $webappName と同じもの。 #html(</div></dv></div></div>) #html(</div>) ** アプリケーションロールの作成 [#qfb72dfa] #html(<div class="pl10">) 左側メニューの [マニフェスト] から、登録したアプリケーションのマニフェストを以下の通り更新する(アプリケーションロールの追加) ※ユニークIDは uuidgen 等を使用して3つ生成しておく。 ※ https://grafana.com/docs/grafana/latest/auth/azuread/ #mycode2(){{ : "appRoles": [ { "allowedMemberTypes": [ "User" ], "description": "Grafana Editor Users", "displayName": "Grafana Editor", "id": "ユニークなID", "isEnabled": true, "lang": null, "origin": "Application", "value": "Editor" }, { "allowedMemberTypes": [ "User" ], "description": "Grafana read only Users", "displayName": "Grafana Viewer", "id": "ユニークなID", "isEnabled": true, "lang": null, "origin": "Application", "value": "Viewer" }, { "allowedMemberTypes": [ "User" ], "description": "Grafana admin Users", "displayName": "Grafana Admin", "id": "ユニークなID", "isEnabled": true, "lang": null, "origin": "Application", "value": "Admin" } ], : "groupMembershipClaims": "ApplicationGroup", : }} #html(</div>) #html(</div>) // ADアプリ 及び シークレットの作成 * ユーザ作成 及び ロールの割当 [#f573268d] #html(<div class="pl10">) ** ユーザの作成 [#d6279ac1] #html(<div class="pl10">) [Azure Active Directory] → [ユーザ] から下図の通りユーザを登録。 #html(<div class="ib border">) &ref(create-users.png,nolink); #html(</div>) #html(</div>) ** ロールの割り当て [#jdcb9361] #html(<div class="pl10">) [Azure Active Directory] → [エンタープライズ アプリケーション] から対象のアプリを選択後に [ユーザーとグループ] を選択して、ユーザにアプリケーションロールを割り当てる。 ※デフォルトで Viewer権限 になるので、割り当てるのは Admin と Editor に該当するユーザだけでOK。 #html(<div class="ib border">) &ref(attach_role.png,nolink); #html(</div>) #html(</div>) #html(</div>) * リソースの作成 [#p10153b6] #html(<div class="pl10">) ** ファイル作成 [#r711498e] #html(<div class="pl10">) シェルの内容は [[Azure App Service に Grafana をデプロイ]] の内容をベースにしている為、以下には変更点のみ記載する。 #html(){{ <div id="tabs1"> <ul> <li><a href="#tabs1-1">0_env.sh</a></li> <li><a href="#tabs1-2">3_app_resources.sh</a></li> </ul> }} // START tabs1-1 #html(<div id="tabs1-1">) 以下を追加 #mycode2(){{ : : # OAuth用 adClientId="クライアントID" adClientSecret="クライアントシークレット" tenantId="テナントID" }} #html(</div>) // END tabs1-1 // START tabs1-2 #html(<div id="tabs1-2">) 環境変数を追加(GF_AUTH_AZUREAD_XXXXX) #mycode2(){{ : : # App Service 環境変数設定 echo "az webapp config appsettings ( $webappName )" az webapp config appsettings set \ -g $resourceGroup -n $webappName \ --settings "GF_SERVER_ROOT_URL=https://${webappName}.azurewebsites.net" \ "GF_SECURITY_ADMIN_PASSWORD=admin" "GF_DATABASE_TYPE=mysql" "GF_DATABASE_HOST=${vmIpAddress}:3306" \ "GF_DATABASE_NAME=grafana" "GF_DATABASE_USER=grafana" "GF_DATABASE_PASSWORD=grafana" \ "WEBSITES_PORT=3000" \ "GF_AUTH_AZUREAD_NAME=Azure AD" \ "GF_AUTH_AZUREAD_ENABLED=true" \ "GF_AUTH_AZUREAD_CLIENT_ID=${adClientId}" \ "GF_AUTH_AZUREAD_CLIENT_SECRET=${adClientSecret}" \ "GF_AUTH_AZUREAD_AUTH_URL=https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize" \ "GF_AUTH_AZUREAD_TOKEN_URL=https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token" \ "GF_AUTH_DISABLE_LOGIN_FORM=true" "GF_AUTH_OAUTH_AUTO_LOGIN=true" \ "GF_AUTH_SIGNOUT_REDIRECT_URL=https://${webappName}.azurewebsites.net/.auth/logout" }} #html(</div>) // END tabs1-2 #html(</div>) // END tabs1 #html(<script>$(function() { $("#tabs1").tabs(); });</script>) #html(</div>) ** リソース作成 [#w558c42c] #html(<div class="pl10">) VMなど #myterm2(){{ ./1_resources.sh --create }} App Service(Grafana) #myterm2(){{ ./3_app_resources.sh --create }} #html(</div>) #html(</div>) * App Service 側の認証/承認設定 [#k753fded] #html(<div class="pl10">) App Service 側もADアプリ側の [[認証設定>#nb493ae5]] と同じ設定をしておく。 #html(<div class="images"><div class="ib">) [App Service] から対象の App Servce アプリを 選択後、「認証/承認」 を選択。 &ref(azure_app_servce_auth1.png,nolink); #html(</div><div class="ib">) ・「オン」、「Active Directory でのログイン」 を選択。 ・認証プロバイダーの Active Directory の選択。 &ref(azure_app_servce_auth2.png,nolink); #html(</div><div class="ib">) Active Directory の設定を下図の通り入力して [OK] ※クライアントID、シークレットは先に登録したADアプリのものを入力。 &ref(azure_app_servce_auth3.png,nolink); #html(</div><div class="ib">) 詳細設定を下図の通り設定して、最後に [保存] を押下・ &ref(azure_app_servce_auth4.png,nolink); #html(</div><div class="ib">) 許可される外部リダイレクト URLは以下の2つを入力しておく。(ADアプリ側に登録したものと同じもの) | 項目 | 設定値 |h | リダイレクトURI | https://Grafanaアプリケーション名.azurewebsites.net/login/azuread | | 〃(2つ目)| https://Grafanaアプリケーション名.azurewebsites.net/.auth/login | | 〃(2つ目)| https://Grafanaアプリケーション名.azurewebsites.net/.auth/login/aad/callback | #html(</div></div>) #html(</div>) * 動作確認 [#ka88153d] #html(<div class="pl10">) #html(<div class="images">) ブラウザから https://Grafanaアプリケーション名.azurewebsites.net にアクセスしてAdminロールを割り当てたユーザでログインしてみる。 ※GF_AUTH_DISABLE_LOGIN_FORM 及び GF_AUTH_OAUTH_AUTO_LOGIN を true にしている為、Grafana のログインフォームは表示されず、最初からOAuth認証が始まる。 #html(<div class="ib">) &ref(grafana-login2.png,nolink); #html(</div><div class="ib">) &ref(grafana-login3.png,nolink); #html(</div><div class="ib">) &ref(grafana-login4.png,nolink); #html(</div><div class="ib">) Admin 権限でログインされている事を確認。 &ref(grafana-login5.png,nolink); #html(</div>) #html(</div>) #html(</div>) * 補足 [#t61a4455] #html(<div class="pl10">) ** ログインURL等について [#fd63636d] #html(<div class="pl10">) Service App アプリの [認証/承認] 設定を行うと、以下のログイン/ログアウトURLが提供され、未ログイン時は自動的に OAuth認証フローが実行されるようになる。 また、このURLを利用してアプリ側でログイン/ログアウト用のリンクを設置したり、ある程度のフロー制御を行う事が出来るようになる。 ※上記の GF_AUTH_SIGNOUT_REDIRECT_URL では .auth/logout を利用している。 | 種別 | URL |h | ログイン | https://アプリケーション名.azurewebsites.net/.auth/login | | ログアウト | https://アプリケーション名.azurewebsites.net/.auth/logout | 尚、Grafana では Aure OAuth認証用のURLとして 「https://サーバ名/login/azuread」 が用意されており、このURLにリダイレクトされる事で認証結果の受け取り等が行われる。 参考: https://grafana.com/docs/grafana/latest/auth/azuread/ #html(</div>) ** Grafana Auth Proxy によるロールマッピングについて [#uaa1d395] #html(<div class="pl10">) プロキシを噛ませてHTTPヘッダで認証できないかやってみたが、 Grafana の Auth Proxy は ロールマッピングには対応していない模様。 https://grafana.com/docs/grafana/latest/auth/overview/ #html(<div class="ib" style="border:1px solid #333;">) &ref(grafana_rolemapping_etc.png,nolink); #html(</div>) #html(</div>) ** ADグループ単位のロール割り当てについて [#cc9e34ff] #html(<div class="pl10">) Active Directory プランによっては、ADグループ単位でのロール割り当ては出来ない。 ※AZURE AD PREMIUM P2 などが必要。 #html(<div class="ib" style="border:1px solid #333;">) &ref(attach_role_etc1.png,nolink); #html(</div>) #html(</div>) #html(</div>)