We are using OAuth via introspection to validate access tokens.
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";
});
This works, mostly.
The Authorization Server response at connect/introspect
is good.
{
"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"
}
A request to the resource server gets past the Authorize
attribute. This is also good.
[Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]
[HttpGet("message")]
public IActionResult GetMessage() {
var identity = User.Identity as ClaimsIdentity;
if (identity == null) {
return BadRequest();
}
return Json(User);
}
The User
though, does not contain the sub
nor the email
properties. It just looks like this:
{
"claims": [
{
"issuer": "LOCAL AUTHORITY",
"originalIssuer": "LOCAL AUTHORITY",
"properties": {},
"subject": {
"authenticationType": "Bearer",
"isAuthenticated": true,
"actor": null,
"bootstrapContext": null,
"claims": []
}
}
]
}
How can we configure our resource server to include the sub
and email
properties in the claims?
Here is our code on GitHub.
The claims are likely there (if they're not, it's a bug in the introspection middleware), but JSON.NET is not very good at serializing Claim
/ClaimsIdentity
/ClaimsPrincipal
, probably because these types have circular references (e.g Claim.Subject
/ ClaimsIdentity.Claims
).
Try using User.FindFirst(ClaimTypes.NameIdentifier)?.Value
and User.FindFirst(ClaimTypes.Email)?.Value
/ to confirm the subject identifier and the email address are there.
If it works, consider returning a projection of your claims instead of a ClaimsPrincipal
instance:
return Json(
from claim in User.Claims
select new { claim.Type, claim.Value }
);
Here is a screenshot the User
in the Debug window.