在Django + Keycloak 25.0.2应用中实现外部认证后通过PythonKeycloak完成无密码强制用户登录
在Django + Keycloak 25.0.2应用中实现外部认证后通过PythonKeycloak完成无密码强制用户登录
嗨,我来帮你梳理下怎么搞定这个需求——用管理员账号的权限在Django + Keycloak 25.0.2里实现外部认证后的无密码强制登录,刚好之前我处理过类似的场景,给你分步骤拆解,都是实操性的内容:
一、先把PythonKeycloak的基础配置搞定
首先得确保你已经装了依赖,没装的话跑这个命令:
pip install python-keycloak
然后用管理员账号初始化KeycloakAdmin客户端,两种方式都可以:要么直接用管理员的用户名密码,要么用你已经拿到的管理员access_token:
方式1:用管理员用户名密码初始化
from keycloak import KeycloakAdmin from keycloak.exceptions import KeycloakError keycloak_admin = KeycloakAdmin( server_url="http://你的Keycloak地址/auth/", username="你的管理员用户名", password="你的管理员密码", realm_name="你的Realm名称", client_id="admin-cli", # Keycloak默认的管理员客户端,不用改 verify=True # 生产环境建议开着,测试环境如果是HTTP可以设为False )
方式2:用已有的管理员access_token初始化
keycloak_admin = KeycloakAdmin( server_url="http://你的Keycloak地址/auth/", realm_name="你的Realm名称", token="你的管理员access_token", verify=True )
二、通过外部认证标识关联Keycloak用户
外部认证完成后,肯定会返回用户的唯一标识(比如手机号、身份证号),你得用这个标识找到Keycloak里对应的用户——如果用户还没在Keycloak里,就用管理员权限创建一个。
查找Keycloak用户
def get_keycloak_user(external_user_id): # 这里假设外部标识对应用户的username,也可以按自定义属性查,比如attributes.external_id users = keycloak_admin.get_users(query={"username": external_user_id}) return users[0] if users else None
不存在则创建Keycloak用户
def create_keycloak_user(external_id, email, first_name, last_name): try: # 用管理员权限创建用户 user_id = keycloak_admin.create_user({ "username": external_id, "email": email, "firstName": first_name, "lastName": last_name, "enabled": True, "attributes": {"external_id": external_id} # 存外部标识方便后续关联 }) return user_id except KeycloakError as e: print(f"创建用户踩坑了:{e}") return None
三、用管理员权限模拟用户获取登录Token
Keycloak 25.0.2支持**用户模拟(Impersonation)**功能,这正是我们需要的——用管理员权限拿到用户的合法access_token,相当于替用户完成了登录。代码很简单:
def get_user_access_token(user_id): try: # 模拟用户,返回的就是用户的登录凭证 impersonation_data = keycloak_admin.impersonate(user_id=user_id) return { "access_token": impersonation_data['access_token'], "expires_in": impersonation_data['expires_in'] } except KeycloakError as e: print(f"模拟用户登录失败:{e}") return None
四、把Keycloak Token绑定到Django会话
拿到用户的access_token后,要让Django识别这个用户并完成登录。这里需要验证Token的有效性,再关联到Django的User模型:
from django.contrib.auth import login, get_user_model from django.http import HttpResponseBadRequest, HttpResponseServerError from keycloak import KeycloakOpenID User = get_user_model() def django_user_login(request, access_token): # 初始化OpenID客户端用于验证Token keycloak_openid = KeycloakOpenID( server_url="http://你的Keycloak地址/auth/", client_id="你的Django应用的Client ID", realm_name="你的Realm名称", client_secret_key="你的Client Secret(如果是机密客户端的话)", verify=True ) try: # 校验Token是否有效 token_info = keycloak_openid.introspect(access_token) if not token_info.get('active'): return False, "Token已经失效了" # 从Token里取用户的唯一标识(sub是Keycloak用户的唯一ID) user_sub = token_info.get('sub') # 关联到Django的User模型,这里要根据你实际的关联逻辑调整 django_user = User.objects.get(username=user_sub) # 完成Django登录,生成会话 login(request, django_user) return True, "登录成功!" except Exception as e: return False, f"登录出错:{str(e)}"
五、串起完整的外部认证登录流程
把上面的步骤串起来,就是完整的业务流程了:
def external_auth_callback(request): # 从外部认证的回调里拿用户的唯一标识 external_user_id = request.GET.get('external_id') if not external_user_id: return HttpResponseBadRequest("没拿到外部用户标识哦") # 1. 找Keycloak用户,没有就创建 kc_user = get_keycloak_user(external_user_id) if not kc_user: # 从外部认证回调里取用户的其他信息 email = request.GET.get('email') first_name = request.GET.get('first_name') last_name = request.GET.get('last_name') new_user_id = create_keycloak_user(external_user_id, email, first_name, last_name) if not new_user_id: return HttpResponseServerError("创建Keycloak用户失败") kc_user = keycloak_admin.get_user(new_user_id) # 2. 模拟用户拿access_token token_data = get_user_access_token(kc_user['id']) if not token_data: return HttpResponseServerError("获取用户登录凭证失败") # 3. 完成Django登录 success, msg = django_user_login(request, token_data['access_token']) if success: # 跳转到首页或者用户中心 return redirect('home') else: return HttpResponseServerError(msg)
一些关键注意事项
- 权限要配对:管理员账号必须有Impersonation权限!去Keycloak后台,找到管理员角色,在「权限」->「客户端权限」->「admin-cli」里勾选
impersonate权限,不然模拟用户会报错。 - 安全要重视:管理员的Token要存在安全的地方(比如环境变量、加密存储),不要明文写在代码里;模拟用户的Token有效期别设太长,Keycloak默认是5分钟,足够用了。
- 外部认证要校验:外部认证的回调一定要做签名校验,防止有人伪造请求冒充用户。
备注:内容来源于stack exchange,提问作者EviSvil
相关产品推荐
相关产品推荐

