未包含在 JWT 中且未发送到 Web Api 的 IdentityServer4 用户声明
Posted
技术标签:
【中文标题】未包含在 JWT 中且未发送到 Web Api 的 IdentityServer4 用户声明【英文标题】:Claims for IdentityServer4 user not included in JWT and not sent to Web Api 【发布时间】:2017-05-30 14:18:08 【问题描述】:按照官方 IdentityServer4 文档,我达到了拥有 MVC 客户端应用程序、IdentityServer4 和 Web Api(正在运行的资源服务器)的地步。 IS4 主页显示用户的所有声明,当使用访问令牌调用 api 时,我们再次得到用户的所有声明。
here 提供了示例代码,尽管它可能不是必需的,我只是遗漏了一些明显的东西。
无论如何,为了简单起见,我们不要从数据库中获取声明,而只是分配一个随机硬编码的声明:
public class ProfileService : IProfileService
public Task GetProfileDataAsync(ProfileDataRequestContext context)
context.IssuedClaims.Add(new System.Security.Claims.Claim("role", "admin"));
return Task.FromResult(0);
...
我在启动文件中注册了自定义配置文件服务,现在当我登录 IS4 时,我看到了附加声明。
但是,当调用 web api(资源服务器)时,这个额外的声明不包含在 JWT 中。 api调用代码:
public async Task<IActionResult> CallApiUsingUserAccessToken()
var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await client.GetStringAsync("http://localhost:5001/identity");
ViewBag.Json = JArray.Parse(content).ToString();
return View("json");
(所有 api 所做的只是返回 User.Claims 列表)。我添加的声明不在其中,当我调试代码并选择访问令牌字符串并在 jwt.io 上对其进行解码时,再次没有这样的声明。
问题是:我错过了什么? HttpContext.Authentication.GetTokenAsync 对我的用例不利吗?如果是,我应该使用什么替代品?
编辑:这里是 OpenId 连接选项(在 MVC 客户端上):
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ClientId = "mvc",
ClientSecret = "secret",
ResponseType = "code id_token",
Scope = "api1", "offline_access" ,
GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true
);
【问题讨论】:
如果您正在使用请提供OpenIdConnectOptions
我不确定我是否理解正确,但仅仅因为您在 Web 方法中在服务器端添加了新声明,并不意味着您重新颁发令牌以实际包含此新声明。尝试任何其他方法,例如删除所有声明,效果应该是一样的。除非您发布新令牌,否则您在服务器上对身份所做的更改是暂时的,并且仅在此类特定请求期间才会持续。类似于从服务器的 cookie 集合中删除 cookie,但不发送新的 set-cookie 以在客户端实际删除它。
【参考方案1】:
我猜原因是您没有为您的 API 分配任何声明。这就是我们根本不调用配置文件服务的原因。
这是一个常见问题,而且有点不一致,因为我们总是调用配置文件服务来获取身份令牌。
我们在 1.0.2 中改变了这种行为
https://github.com/IdentityServer/IdentityServer4/releases/tag/1.0.2
请再试一次,看看这是否会给您带来预期的结果。
【讨论】:
确实如此,非常感谢!我想这从来都不是错误,但是新的 IS4 版本省去了很多麻烦,因为 openId connect 的大多数方面确实不直观。 如果没有在 AspNetUserClaims 中明确添加,如何添加电子邮件和用户名声明? @leastprivilege 澄清一下,您是说通过此修改,IProfileService 设置的声明现在总是添加到身份令牌和访问令牌?而旧的行为只是将它们附加到身份令牌?这似乎是我所看到的,从 1.0.0 移动到 1.1.1。 从阅读the code 的那个提交,看起来IProfileService
确实为每个令牌类型查询。以上是关于未包含在 JWT 中且未发送到 Web Api 的 IdentityServer4 用户声明的主要内容,如果未能解决你的问题,请参考以下文章