我正在尝试使用 ADFS 2016 作为 STS 在应用程序中实现“代表”流程。作为参考,我查看了这个 Microsoft 教程(https://learn.microsoft.com/en-ca/windows-server/identity/ad-fs/development/ad-fs-on-behalf-of-authentication-在 Windows 服务器中)。它正常工作,我可以登录到我的 Web 应用程序,然后在 UserAssertion 中使用我的原始访问令牌来生成一个新的访问令牌,并有适当的受众来调用我的 API,但我发现绝对没有办法包含任何用户信息(子、名称、电子邮件、upn 等)到我的 API 的访问令牌中,即使我将声明规则设置到 API 的 ADFS 配置中也是如此。
我使用 Fiddler 检查了我的应用程序和 adfs 之间的通信,一切看起来都像教程中的信息。请参阅下面“代表”请求的屏幕截图:
这是生成的访问令牌:
最后,这是我用来生成新访问令牌的代码:
private async Task<string> GetAccessToken(ClaimsPrincipal user, string originalAccessToken)
{
var authority = "[authority]";
var context = new AuthenticationContext(authority, false);
string userName = user.FindFirstValue("upn");
var userAssertion = new UserAssertion(originalAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer",userName);
var cc = new ClientCredential("https://localhost:44387/", "[client_secret]");
var result = await context.AcquireTokenAsync("https://localhost:44339/", cc, userAssertion);
return result.AccessToken;
}
您是否遇到过这种情况?如果是,您是否找到了解决此问题的方法?
谢谢
我仅将 Microsoft 代表流程与 Azure AD 结合使用,而不是 ADFS,但您似乎需要在用户信息请求中发送更详细的范围。
也许可以尝试发送“openid 个人资料电子邮件”,以表明您需要此类详细信息,如我的博文第 17 节中所示。当然,这是假设此类数据已为所有用户注册。
故障排除看起来原因之一是:
一个次优的 Microsoft 库,不允许您发送所需的范围
您获得正确的数据并可以更新您的代码
发出索赔的现有规则可能无法正常工作,因为“代表”请求会生成不同的传入索赔集。
一种检查方法是创建新的自定义规则并让所有传入的索赔通过。 即
x:[]
=> issue(claim = x);
如果您想要的值出现在访问令牌中,那么只需制定正确的声明过滤器即可。
对于那些从 JWT 用户断言发出的。例如来自原始帖子
> var userAssertion = new UserAssertion(originalAccessToken,
> "urn:ietf:params:oauth:grant-type:jwt-bearer",userName);
如果原始访问令牌中存在名为“myclaim”的声明,则这似乎在声明集中可用:
c:[Type == "uri:jwt/myclaim"]