如何在Django OAuth Toolkit中修改ID Token的sub声明?
修改Django OAuth Toolkit OIDC ID Token中的sub声明
问题背景
使用Django OAuth Toolkit(DOT)结合OIDC时,请求指定openid scope会返回包含id_token的响应,其中sub字段默认使用用户数据库主键,存在暴露内部数据的风险。需要将其替换为自定义的唯一标识。
此前尝试自定义OAuthLibCore后端重写create_token_response方法,但此时token已生成,无法修改。
解决方案:重写OAuthValidator类的相关方法
DOT的ID Token生成逻辑在oauth2_provider.oauth2_validators.OAuth2Validator类中,核心是get_claim_dict方法负责生成包含sub的声明字典。通过继承并重写该类,可实现自定义sub值。
步骤1:创建自定义Validator类
在项目中创建自定义验证器类,继承自OAuth2Validator,重写get_claim_dict方法,替换sub为所需的唯一标识(比如用户UUID、自定义唯一ID等):
from oauth2_provider.oauth2_validators import OAuth2Validator class CustomOAuth2Validator(OAuth2Validator): def get_claim_dict(self, request): # 先调用父类方法获取基础声明,再替换sub claims = super().get_claim_dict(request) # 替换sub为用户的自定义唯一标识,根据你的用户模型字段调整 claims["sub"] = str(request.user.uuid) return claims
若需要更灵活的控制(比如同时修改其他声明),也可以重写官方推荐的finalize_id_token方法:
from oauth2_provider.oauth2_validators import OAuth2Validator class CustomOAuth2Validator(OAuth2Validator): def finalize_id_token(self, id_token, token, token_handler, request): # 调用父类方法获取基础ID Token字典 id_token = super().finalize_id_token(id_token, token, token_handler, request) # 修改sub字段 id_token["sub"] = str(request.user.uuid) # 可额外添加或修改其他声明 # id_token["custom_claim"] = "custom_value" return id_token
步骤2:配置项目使用自定义Validator
在Django的settings.py中添加配置,指定使用自定义验证器类:
OAUTH2_PROVIDER = { # 其他配置项... "OAUTH2_VALIDATOR_CLASS": "your_app.path.to.CustomOAuth2Validator", }
原理说明
DOT生成ID Token的流程:
- 请求包含
openidscope时,触发OIDC相关逻辑 get_id_token方法负责生成ID Token,其中调用finalize_id_tokenfinalize_id_token调用get_id_token_dictionary,进而通过get_claim_dict获取用户声明- 重写
get_claim_dict或finalize_id_token,可在ID Token生成阶段修改sub及其他声明
内容的提问来源于stack exchange,提问作者Dushyant Deshwal
相关产品推荐
相关产品推荐

