0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Tableau OnlineへのJWTを用いたSSO

Last updated at Posted at 2022-11-15

ハロー世界。りくとんです。みんな元気にSSOしてますか?(挨拶)

この記事はTableau Onlineの埋め込みビューに対してSSOするために、2022年1月に実装された連携アプリの機能を利用して実装した記事です。
一応(あんま役に立たない)公式ヘルプ載せときますね。

◆Tableau Cloud ヘルプ - 直接信頼を使用して接続済みアプリを構成する
https://help.tableau.com/current/online/ja-jp/connected_apps_direct.htm

概要

・Tableau Onlineの埋め込みビューに対してSSO。
・SAML認証のIdP立てるのだるいし借りるとランニングが…。→連携アプリで解決。
・JWT発行するにはPythonかJavaのサンプルコードが載ってた。今回はPythonで実装。
・環境依存したくないからGAE上にデプロイしよう。AjaxでJWT取得してSSO。
・JWTとはなんぞやという知識は先人のQiitaを参考にしてください。

◆Qiita - 認証におけるJWTの利用について
https://qiita.com/shnmorimoto/items/a38690929d7d84bbdea6

Tableau OnlineにおけるJWTを利用したSSO相関図

1.png

Tableau Onlineにて連携アプリの設定

・設定→連携アプリ→新しい連携アプリへアクセス
2.png
・連携アプリの設定。ドメインを指定する場合は後述のGAEのホストを指定。
3.png
・シークレットID、シークレット値(Key)の払い出し
4.png
・クライアントID、シークレットID、シークレット値(Key)の保存。
 後ほどapp.yaml、seacret.yamlの設定に使用。
5.png
・作成した連携アプリの有効化
6.png

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 Online上に登録済みのメールアドレス★】"

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のインストール
 https://cloud.google.com/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対象のダッシュボードまで移動し、共有を選択。
7.png
・埋め込みコードのコピーを選択。
8.png

埋め込みコードのコピー例.js
<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のランニングコストも生じないのでリーズナブル。
・seacretkey抜かれると終わるのでgit上にuploadしないよう注意。
 (.gcloudignoreで制御)
・比較的新しい機能なので文献無さすぎてキレてた。ので記事書いた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?