WS-Federation Azure AD代理流程:获取原始Token为空问题求助
我之前也遇到过类似的困扰——在WS-Federation结合Cookie认证的架构里,默认配置不会把原始Token留存下来,直接导致OBO流程因为拿不到originalToken而失败。下面是我亲测有效的解决步骤:
1. 让WS-Federation中间件保存原始Token
WS-Federation中间件默认不会把Azure AD返回的原始断言(比如SAML 1.1或JWT)存储到HttpContext里,你需要在配置中间件时显式开启SaveTokens选项:
services.AddAuthentication(WsFederationDefaults.AuthenticationScheme) .AddWsFederation(options => { options.Wtrealm = Configuration["AzureAd:Wtrealm"]; options.MetadataAddress = Configuration["AzureAd:MetadataAddress"]; // 关键配置:将原始Token保存到AuthenticationProperties中 options.SaveTokens = true; });
2. 从HttpContext中正确提取原始Token
开启SaveTokens后,原始Token会被存在认证属性里。你可以通过以下代码获取:
// 先获取当前的认证结果 var authResult = await HttpContext.AuthenticateAsync(WsFederationDefaults.AuthenticationScheme); if (!authResult.Succeeded) { // 处理认证失败的情况,比如用户未登录 return Unauthorized(); } // 提取原始Token——注意WS-Federation默认返回的是id_token(SAML断言),如果是访问API的token可能是access_token var originalToken = authResult.Properties.GetTokenValue("id_token"); // 不确定的话,可以遍历所有存储的Token类型,确认哪个是你需要的 foreach (var token in authResult.Properties.GetTokens()) { Debug.WriteLine($"Token类型:{token.Name},值:{token.Value}"); }
3. 确保Cookie认证中间件也保留Token
因为你同时使用Cookie认证,需要确保Cookie中间件也会把这些Token保存到Cookie的属性中,这样后续请求才能从Cookie里拿到Token:
services.AddCookie(options => { options.SaveTokens = true; // 其他Cookie相关配置(比如过期时间、路径等) });
4. 正确创建UserAssertion
拿到originalToken后,要根据Token的类型选择对应的断言类型:
- 如果是SAML 1.1断言,使用
urn:oasis:names:tc:SAML:1.0:assertion作为类型 - 如果是JWT Token,使用
urn:ietf:params:oauth:grant-type:jwt-bearer作为类型
示例代码:
// 假设拿到的是SAML断言 var userAssertion = new UserAssertion(originalToken, "urn:oasis:names:tc:SAML:1.0:assertion"); // 之后就可以用这个断言调用Azure AD的OBO流程获取目标API的Token var tokenRequest = new ClientCredentialsTokenRequest { Address = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token", ClientId = webAppClientId, ClientSecret = webAppClientSecret, GrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer", Assertion = userAssertion.Assertion, Scope = "api://target-api-client-id/.default" }; var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(tokenRequest);
额外排查点
- 确认Azure AD应用注册配置:你的Web应用必须拥有目标Web API的Delegated权限,并且已经获得管理员同意
- 验证用户状态:确保
HttpContext.User.Identity.IsAuthenticated为true,即用户已经完成WS-Federation认证 - 检查Token有效期:如果原始Token已过期,OBO流程会失败,但当前问题是Token为null,所以先确保能成功提取到Token
内容的提问来源于stack exchange,提问作者Matthew Christianson
相关产品推荐
相关产品推荐

