はじめに
どうも!ecbeing20年目のYです。
今回はTableau Cloudの埋め込みビューに対してSSOするために、2022年1月に実装された連携アプリの機能を利用して実装してみました。 その手法をご紹介します。
◆(参考) Tableau Cloud ヘルプ - 直接信頼を使用して接続済みアプリを構成する https://help.tableau.com/current/online/ja-jp/connected_apps_direct.htm
- はじめに
- 概要
- Tableau Onlineにて連携アプリの設定
- JWTを払い出すためのコードを作成
- GCPの作成
- GAEへのデプロイ
- 埋め込みビューの準備
- SSO呼び出し元ファイルの作成
- まとめ
- お知らせ
概要
・Tableau Cloudの埋め込みビューに対してSSOしたい!
・SAML認証のIdP立てるのは工数がかかってしまう。しかし借りるとランニングが…。そうだ!連携アプリで解決しよう!
・JWT発行するにはPythonかJavaのサンプルコードが公式ヘルプに載っていた。今回はPythonで実装!
・環境依存したくないのでGAE上にデプロイ!AjaxでJWT取得してSSOを実現!
・JWTとはなんぞやという方は下記の記事を参考にしてください!
◆JWTの基本のキ https://blog.ecbeing.tech/entry/2024/12/25/080000
Tableau Onlineにて連携アプリの設定
・設定→連携アプリ→新しい連携アプリへアクセス
・連携アプリの設定。ドメインを指定する場合は後述のGAEのホストを指定。
・シークレットID、シークレット値(Key)の払い出し
・クライアントID、シークレットID、シークレット値(Key)の保存。
後ほどapp.yaml、seacret.yamlの設定に使用。
・作成した連携アプリの有効化
JWTを払い出すためのコードを作成
・下記5ファイルを"jwt"ディレクトリ上に作成
main.py
from flask import Flask from flask_cors import CORS import jwt import datetime import uuid import os token = jwt.encode( { 'iss': os.getenv('connectedAppClientId'), 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5), 'jti': str(uuid.uuid4()), 'aud': 'tableau', 'sub': os.getenv('connectedAuthMailAddress'), 'scp': ['tableau:views:embed'] }, os.getenv('connectedAppSecretKey'), algorithm = 'HS256', headers = { 'kid': os.getenv('connectedAppSecretId'), 'iss': os.getenv('connectedAppClientId') } ) app = Flask(__name__) CORS(app) @app.route('/') def jwt(): return token
requirements.txt
pyjwt==2.6.0 flask==2.1.0 Flask-Cors==3.0.10
app.yaml
runtime: python311 service: jwt env_variables: connectedAppClientId: "【★クライアントID★】" connectedAppSecretId: "【★シークレットID★】" connectedAuthMailAddress: "【★該当PRJに権限を持ったTableau Cloud上に登録済みのメールアドレス★】" includes: - secret.yaml
secret.yaml
env_variables: connectedAppSecretKey: "【★シークレット値(Key)★】"
.gcloudignore(追記)
secret.yaml
GCPの作成
①Googleアカウントを取得する
https://accounts.google.com/signup/v2/webcreateaccount?flowEntry=SignUp
②GCPのコンソールへアクセス
https://console.cloud.google.com/
③新しいプロジェクトを作成
GAEへのデプロイ
①Cloud SDKのインストール
②コマンドプロンプトを起動
③gcloud initコマンドの実行
Googleへのログイン確認メッセージが出力されるため「Y」を入力。(WEBブラウザが開く)
あらかじめGCPにて権限付与が済んでいるアカウントでGoogleログインを行う。
Cloud SDK のリクエストを許可する。
④プロジェクトIDの選択
使用するGoogle Cloud PlatformのプロジェクトIDを選択する。
⑤Google App Engineへのデプロイ
・CD [Path]コマンド用いてWEBアプリケーションのルートディレクトリ(ソースファイル一式の「jwt\app.yaml」が配置されているディレクトリ)へ移動する。
・以下のコマンドを実行してデプロイ作業を開始する。
gcloud app deploy
・デプロイの最終確認メッセージが出力されるため「Y」を入力する。
⑥App Engineのサービス画面へ遷移する。
https://console.cloud.google.com/appengine/services
⑦サービスの「jwt」部分のリンクからURLを取得する。
https://jwt-dot-[プロジェクトID].[リージョンコード].r.appspot.com/
アクセスするとJWT(Json Web Token)が表示される。
埋め込みビューの準備
・SSO対象のダッシュボードまで移動し、共有を選択。
・埋め込みコードのコピーを選択。
埋め込みコードのコピー例
<script type='module' src='https://us-east-1.online.tableau.com/javascripts/api/tableau.embedding.3.latest.min.js'></script> <tableau-viz id='tableau-viz' src='【ダッシュボードURL】' width='1757' height='1111' toolbar='bottom' ></tableau-viz>
上記のtableau-vizの引数としてtoken=でJWTを渡せばSSOできる。
SSO呼び出し元ファイルの作成
・今回はHTMLファイルにて実装。
・JavaScript経由でAjax通信を行い、main.pyを呼び出してJWTを取得。
・応答が返ってきたら埋め込みビュー用のScriptを呼び出してtokenを渡しSSOを実現。
sample.html
<html> <head></head> <body> <script type="module" src="https://us-east-1.online.tableau.com/javascripts/api/tableau.embedding.3.latest.min.js"></script> <div id="tableau"></div> <script> var tableaudiv = document.getElementById("tableau"); var jwt = new XMLHttpRequest(); jwt.onreadystatechange=function(){ if(jwt.readyState==4){ tableaudiv.innerHTML = '\ <tableau-viz id="tableau-viz"\ src="【埋め込みビューのURL】"\ token="' + jwt.responseText + '"\ width="1760" height="1111" toolbar="bottom" >\ </tableau-viz>\ '; } } jwt.open('GET','https://jwt-dot-[プロジェクトID].[リージョンコード].r.appspot.com/'); jwt.send(); </script> </body> </html>
まとめ
・SAML使うよりも簡単にSSOを実現することができる。
・IdPのランニングコストも生じないのでリーズナブルな運用が可能。
・secretkeyが抜かれないように、git上にuploadしないよう注意。 (.gcloudignoreで制御)
お知らせ
ecbeingでは新進気鋭なエンジニアを募集しております!
careers.ecbeing.tech