コンテンツにスキップ

パッケージ@Flask

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. authlib.integrations.flask_client

authlib.integrations.flask_clientとは


初期化

▼ 全体

特にKubernetes内では、api_base_urlauthorize_urlのドメインに、外部から接続できるKeycloakのドメインを設定する。

一方で、access_token_urljwks_uriはKubernetes内部からのみ接続できるように、Serviceのドメインとする。

from authlib.integrations.flask_client import OAuth

app = Flask(__name__)

oauth = OAuth(app)

oauth.register(
    # 例:keycloak、googleなど
    name="<IDプロバイダー名>",
    client_id="foo-client",
    client_secret="*****",
    client_kwargs={"scope": "openid profile email"},
    # 外部から接続できるKeycloakのドメインを設定する。Kubernetes Serviceのドメインではダメ。
    api_base_url="http://<KeycloakのAPIのドメイン (Serviceの完全修飾ドメイン名) >/",
    # 外部から接続できるKeycloakのドメインを設定する。Kubernetes Serviceのドメインではダメ。
    authorize_url="http://<KeycloakのWebのドメイン>/realms/<realm名>>/protocol/openid-connect/auth",
    # Serviceの完全修飾ドメイン名
    access_token_url="http://<KeycloakのAPIのドメイン>:8080/realms/dev/protocol/openid-connect/token",
    # Serviceの完全修飾ドメイン名
    jwks_uri="http://<KeycloakのAPIのドメイン (Serviceの完全修飾ドメイン名) >:8080/realms/dev/protocol/openid-connect/certs"
)

IDプロバイダー名を指定し、ここで設定した変数を取得できる。

# http://<KeycloakのAPIのドメイン>/
print(oauth.<IDプロバイダー名>.api_base_url)


ログイン

▼ 全体

from flask import url_for, redirect

@app.route('/login')
def login():
    redirect_uri = url_for("callback", _external=True)
    return oauth.keycloak.authorize_redirect(redirect_uri)

@app.route("/callback")
def callback():
    # 認可レスポンスを取得する
    authorization_response = oauth.keycloak.authorize_access_token()

    # アクセストークンやIDトークンをセッションデータとして保存する
    session['access_token'] = authorization_response['access_token']
    session['id_token'] = authorization_response['id_token']

    # デコードしたIDトークンを認可レスポンスから取得する
    id_token = oauth.keycloak.parse_id_token(authorization_response, None)
    session['user'] = id_token['given_name']

    # ホームにリダイレクトする
    redirect_uri = url_for('front', _external=True)
    return redirect(redirect_uri)


ログアウト

▼ 全体

from flask import url_for, redirect

@app.route('/logout')
def logout():
    # Keycloakからログアウトする
    redirect_uri = ("<KeycloakのWebのドメイン>/realms/dev/protocol/openid-connect/logout?id_token_hint=%s&post_logout_redirect_uri=%s" % (session.get('id_token', ''), url_for("front", _external=True)))

    # セッションデータを削除する
    session.pop('access_token', None)
    session.pop('id_token', None)
    session.pop('user', None)

    return redirect(redirect_uri)


02. flask_oidc.OpenIDConnect

flask_oidc.OpenIDConnectとは

from flask_oidc import OpenIDConnect

app = Flask(__name__)

app.config.update({
    # client_secrets.jsonファイルのパスを設定する
    'OIDC_CLIENT_SECRETS': 'client_secrets.json',
    'OIDC_SCOPES': ['openid', 'profile', 'email'],
})

oidc = OpenIDConnect(app)


client_secrets.json

認証情報をJSONファイルで定義する。

{
  "web":
    {
      "issuer": "http://localhost:8081/realms/<realm名>",
      "auth_uri": "http://localhost:8081/realms/<realm名>/protocol/openid-connect/auth",
      "client_id": "flask-app",
      "client_secret": "a41060dd-b5a8-472e-a91f-6a3ab0e04714",
      "redirect_uris": ["http://localhost:5000/*"],
      "userinfo_uri": "http://localhost:8081/realms/<realm名>/protocol/openid-connect/userinfo",
      "token_uri": "http://localhost:8081/realms/<realm名>/protocol/openid-connect/token",
      "token_introspection_uri": "http://localhost:8081/realms/<realm名>/protocol/openid-connect/token/introspect",
    },
}