使 User.Identity 包含访问令牌负载中的电子邮件地址

Make the User.Identity include the email address from the access token payload

我们通过内省使用 OAuth 来验证访问令牌。

app.UseOAuthIntrospection(options =>
{
    options.AutomaticAuthenticate = true;
    options.AutomaticChallenge = true;
    options.Authority = "http://localhost:12345/";
    options.Audiences.Add("ResourceServer01");
    options.ClientId = "ResourceServer01";
    options.ClientSecret = "secret_secret_secret";
});

这主要是有效的。

connect/introspect 的授权服务器响应良好。

{
  "active": true,
  "iss": "http://localhost:12345/",
  "sub": "797264b3-194c-483f-08fb-08d3cbab9158",
  "scope": "openid email roles",
  "iat": 1471998289,
  "nbf": 1471998289,
  "exp": 1472000089,
  "jti": "274cbb7f-9412-4d69-8c02-ca6a500b4a36",
  "token_type": "Bearer",
  "aud": [
    "ResourceServer01",
    "ResourceServer02"
  ],
  "email": "shaun@bigfont.ca",
  "AspNet.Identity.SecurityStamp": "4956a5c3-9efd-4f51-9746-43a187698e1e"
}

对资源服务器的请求通过了 Authorize 属性。这也不错。

[Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]
[HttpGet("message")]
public IActionResult GetMessage() {
    var identity = User.Identity as ClaimsIdentity;
    if (identity == null) {
        return BadRequest();
    }
    return Json(User);
}

虽然 User 不包含 sub 也不包含 email 属性。它看起来像这样:

{
    "claims": [
        {
            "issuer": "LOCAL AUTHORITY",
            "originalIssuer": "LOCAL AUTHORITY",
            "properties": {},
            "subject": {
                "authenticationType": "Bearer",
                "isAuthenticated": true,
                "actor": null,
                "bootstrapContext": null,
                "claims": []
            }
        }
    ]
}

我们如何配置资源服务器以在声明中包含 subemail 属性?

这里是our code on GitHub.

声明可能在那里(如果不是,那是内省中间件中的错误),但是 JSON.NET 不是很擅长序列化 Claim/ClaimsIdentity/ ClaimsPrincipal,可能是因为这些类型有循环引用(例如 Claim.Subject / ClaimsIdentity.Claims)。

尝试使用 User.FindFirst(ClaimTypes.NameIdentifier)?.ValueUser.FindFirst(ClaimTypes.Email)?.Value/ 确认主题标识符和电子邮件地址。

如果有效,请考虑返回您声明的投影而不是 ClaimsPrincipal 实例:

return Json(
    from claim in User.Claims 
    select new { claim.Type, claim.Value }
);

这是调试 window 中 User 的屏幕截图。