Closed RobRolls closed 9 years ago
One more thing. I did try manually adding a given_name claim to the AspNetUserClaims table for the user in question. The resulting id_token did then contain the given_name claim with the value I entered in the AspNetUserClaims table. How is this supposed to work?
Does your user have those claims?
Also, is the client requesting id_token and token?
The client is requesting id_token and token.
The user does not have a claim for given_name or family_name. But this is the crux of my question. Using AspNetIdentity will the given_name and famly_name values be supplied from the AspNetIdentityUser table or does there need to be a seperate claim outside of the values in the User table?
The thing that made me really think it should just pull the name values from the User table is that when the email scope is requested and the user does not have a claim for email the id_token ends up including an email claim that has the value from the user table. No additional claim necessary.
When you request id_token and token then not all identity scope claims go into the id_token, unless you set the include in token setting. If they're not in the token, those claims are expected to be loaded from the user info endpoint using the access token. That's how OIDC designed it.
The given_name and family_name claims are not populated whether you hit the userinfo endpoint or not.
Looking through the AspNetIdentityUserService.GetClaimsFromAccount
method I can see that email claims are added, phone number claims, user claims, and role claims. Unless family_name and given_name claims are actually claims in the UserClaims table i don't see how they would get added normally.
There is a related example in the SelfHost.AspId.ClaimsIdentityFactory Example
public override async System.Threading.Tasks.Task<System.Security.Claims.ClaimsIdentity> CreateAsync(UserManager<User, string> manager, User user, string authenticationType)
{
var ci = await base.CreateAsync(manager, user, authenticationType);
if (!String.IsNullOrWhiteSpace(user.FirstName))
{
ci.AddClaim(new Claim("given_name", user.FirstName));
}
if (!String.IsNullOrWhiteSpace(user.LastName))
{
ci.AddClaim(new Claim("family_name", user.LastName));
}
return ci;
}
Problem is if I implement this the CreateAsync
method on the ClaimsIdentityFactory
only gets called authenticating external accounts.
I went ahead and overrode GetClaimsFromAccount
in my UserService
which simply inherits from AspNetIdentityUserService
to also add the first and last names from the User. This works but I feel like I'm doing something wrong and this should work out of the box.
No that's the right place. There was a reason we didn't use the ClaimsIdFactory, but I forget why.
Thanks for the help.
I have idsvr3 runniing with AspNetIdentity providing the user store. When I authenticate I do not end up with any profile claims other than the preferred_username in my resulting id_token. I'm requesting the openid, profile, and roles scopes. I have the users in the AspNetUsers table. I do end up with the email and email_verified claims properly populated from the data in the AspNetUsers table. I do see the preferred_username profile claim but that's the only one. I'm specifically looking for the family_name and given_name.
Should these values come out of the AspNetUsers table automatically or do I need to get them manually inside my own GetProfileDataAsync on the idsvr? Is there some configuration I need to have setup?
Thanks