Claim
objects are a bit more than just a simple string, and what you are looking at in the userClaimsList
is a list of these claim objects.
Claims are mostly pairs of a claim type and a claim value, and when you look for certain information about a user, you should use the claim type to identity the user property you are looking for.
What you do in your code is assume that the claim you are looking for is the third to last, which by itself is already a dangerous assumption since you cannot be sure that this will always be the case: claims are generally considered unordered and you should look for them by type. And once you get the type, you then .ToString()
it, which essentially reduces all the information the Claim
type has down to a single string of the format claimType: claimValue
. You can use that, but it’s really inefficient when the object itself as a much better way of accessing the claim value.
Since you are looking for the prefix "preferred_username: "
, I assume that preferred_username
is the claim type you are looking for. In that case, you could look up that claim like this:
var claim = HttpContext.User.Claims.First(c => c.Type == "preferred_username");
var emailAddress = claim.Value;
The use of First
will throw an exception if a claim with that type was not found. If you don’t want that, you can use FirstOrDefault
and then check whether claim
is null
.
There are also a few helper extensions that allow you to extract claims directly. In this case, you could use FindFirstValue
on the user to get the claim value directly:
var emailAddress = HttpContext.User.FindFirstValue("preferred_username");
In case a claim with that type was not found, FindFirstValue
will return null
, so emailAddress
could be null
in this case.