Flask OIDC集成Keycloak问题:登录状态无法被识别
问题描述
本地Flask站点使用Flask OIDC对接Keycloak服务时遇到以下问题:
- 能正常跳转到Keycloak登录页面并完成登录,但重定向回站点后,登录状态不被识别。
- 给路由添加
@oidc.require_login装饰器会引发站点与Keycloak的无限循环(Keycloak已识别登录状态,无需重复登录),调用oidc.user_loggedin也始终显示未认证。 - 偶尔出现错误:
*Unauthorized mismatching_state: CSRF Warning! State not equal in request and response.*,错误提示指出“session” Cookie缺少有效的“SameSite”属性,不清楚如何修改该属性。
相关代码
Flask应用代码
from flask import Flask from flask import render_template import logging from flask import url_for from flask import redirect from flask import request from flask import jsonify from flask import send_file import os import json import requests from flask_oidc import OpenIDConnect import psycopg2 from flask import session app = Flask(__name__) app.config.update({ 'SECRET_KEY': 'VerySecret', 'TESTING': True, 'DEBUG': True, 'OIDC_CLIENT_SECRETS': 'client_secrets.json', 'OIDC_COOKIE_SECURE': False, 'OIDC_USER_INFO_ENABLED': True, 'OIDC_SCOPES': ['openid', 'email', 'profile'] }) oidc = OpenIDConnect(app) @app.route('/loging') def loging(): return redirect(url_for('oidc_auth.login')) @app.route('/test') @oidc.require_login def sitetest(): return 'Hallo' @app.route('/') def start(): if(oidc.user_loggedin==True): return render_template("login.html") else: nice = 'You are not logged in! ' + str(oidc.user_loggedin) return nice
client_secrets.json配置
{ "web": { "issuer": "http://127.0.0.1:8080/realms/elrealm", "auth_uri": "http://127.0.0.1:8080/realms/elrealm/protocol/openid-connect/auth", "client_id": "elre", "client_secret": "NSIsn********************", "redirect_uris": ["http://127.0.0.1:5000/*"], "userinfo_uri": "http://127.0.0.1:8080/realms/elrealm/protocol/openid-connect/userinfo", "token_uri": "http://127.0.0.1:8080/realms/elrealm/protocol/openid-connect/token", "token_introspection_uri": "http://127.0.0.1:8080/realms/elrealm/protocol/openid-connect/token/introspect" } }
解决方案
1. 配置SameSite Cookie属性
Flask的session Cookie和Flask-OIDC的认证Cookie都需要设置SameSite属性,在app.config中添加:
app.config.update({ # 原有配置... 'SESSION_COOKIE_SAMESITE': 'Lax', 'OIDC_COOKIE_SAMESITE': 'Lax' })
本地测试用Lax足够,生产环境可根据需求调整为Strict。
2. 修正redirect_uris配置
Keycloak和client_secrets.json中的redirect_uris建议指定具体回调路径(Flask-OIDC默认回调路径为/oidc_callback),修改为:
"redirect_uris": ["http://127.0.0.1:5000/oidc_callback"]
同时在Keycloak客户端配置中同步更新该地址。
3. 禁用TESTING模式
TESTING模式会导致Flask session行为异常,关闭该模式:
'TESTING': False,
4. 修复登录路由拼写错误
将/loging路由修正为/login:
@app.route('/login') def login(): return redirect(url_for('oidc_auth.login'))
5. 使用安全的SECRET_KEY
替换测试用的VerySecret为随机生成的安全密钥:
import secrets app.config['SECRET_KEY'] = secrets.token_hex(16)
SECRET_KEY用于加密session,不安全的密钥会导致session无法正常持久化和验证。
内容的提问来源于stack exchange,提问作者Weizenfredi
相关产品推荐
相关产品推荐

