Azure B2C编辑资料后回调获取新令牌出错的问题排查
问题解答
1. 编辑资料用户流是否需要生成新令牌?
需要。用户完成资料编辑后,Azure B2C会返回新的授权码,用于获取包含更新后用户信息的新id_token和access_token。原令牌中的用户信息已过时,获取新令牌能确保会话中存储的用户数据是最新的。
2. 错误根源分析
错误AADB2C90088的核心原因是:授权码是针对登录用户流(B2C_1_signupsignin_20220810)生成的,但你用它去调用资料编辑用户流(B2C_1_profileediting)的令牌端点。
问题出在_get_token_from_code函数中:构建MSAL应用时未传入资料编辑用户流对应的authority参数,默认使用了登录用户流的authority,导致授权码与令牌端点不匹配,Azure B2C拒绝颁发令牌。
后续的KeyError: 'id_token_claims'是因为acquire_token_by_auth_code_flow调用失败,返回的result中没有id_token_claims字段,而是包含错误信息。
代码修复方案
需要确保获取令牌时使用的authority和发起认证流时的authority一致,具体修改如下:
1. 存储认证流对应的authority到会话
修改sign_in和editprofile函数,在保存auth_flow的同时记录对应的authority:
def sign_in(request): flow = _build_auth_code_flow() try: request.session['auth_flow'] = flow # 保存当前认证流的authority request.session['auth_flow_authority'] = os.getenv("AUTHORITY") except Exception as e: print(e) return HttpResponseRedirect(flow['auth_uri']) def editprofile(request): authority = os.getenv("B2C_PROFILE_AUTHORITY") flow = _build_auth_code_flow(authority=authority) try: request.session['auth_flow'] = flow # 保存当前认证流的authority request.session['auth_flow_authority'] = authority except Exception as e: print(e) return HttpResponseRedirect(flow['auth_uri'])
2. 使用保存的authority构建MSAL应用
修改_get_token_from_code函数,取出会话中保存的authority用于令牌获取:
def _get_token_from_code(request): cache = _load_cache(request) # 取出保存的authority,默认使用登录用户流的authority authority = request.session.pop('auth_flow_authority', os.getenv("AUTHORITY")) auth_app = _build_msal_app(cache, authority=authority) flow = request.session.pop('auth_flow', {}) result = auth_app.acquire_token_by_auth_code_flow(flow, request.GET) _save_cache(request, cache) return result
3. 增强回调函数的错误处理
避免因令牌获取失败导致的KeyError:
def callback(request): result = _get_token_from_code(request) print(result) # 检查是否存在错误 if 'error' in result: request.session['flash_error'] = f"{result['error']}: {result['error_description']}" return redirect('index') # 成功获取令牌后更新会话中的用户信息 _store_user(request, result['id_token_claims']) return redirect('home')
额外说明
- Azure B2C的每个用户流(登录、注册、资料编辑等)都是独立端点,授权码只能用于对应用户流获取令牌,不能跨流使用。
- 资料编辑后获取的新
id_token包含更新后的用户信息,需调用_store_user更新会话数据,确保前端展示最新资料。
内容的提问来源于stack exchange,提问作者Goncalves
相关产品推荐
相关产品推荐

