Reference for Constants.ClaimTypes
Asked Answered
J

4

10

I've got IdentityServer3 running as a standalone identity server.

I have a separate MVC client that uses Cookies and OpenIdConnect for authentication. I'm trying to set up claims transformations amongst other things, and would like to reference the different claims types like so:

var givenName = id.FindFirst(Constants.ClaimTypes.GivenName);
var familyName = id.FindFirst(Constants.ClaimTypes.FamilyName);
var sub = id.FindFirst(Constants.ClaimTypes.Subject);
var roles = id.FindAll(Constants.ClaimTypes.Role);

On the IdentityServer3, I reference these using Thinktecture.IdentityServer.Core.Constants however on my MVC client I don't think I should need to reference Thinktecture.IdentityServer3 just for these string constants? Is there a client library that is recommended to be used in this case? I've tried Thinktecture.IdentityModel and some .NET references but none seem to replicate the ClaimTypes in Thinktecture.IdentityServer.Core.Constants. The best I've found is System.Security.Claims.ClaimTypes but that seems to have several missing e.g. FamilyName.

The first placed I looked was Thinktecture.IdentityModel but was surprised these aren't there.

So what's the magic reference? Or is it appropriate to load Thinktecture.IdentityServer3 just for these strings?

Thanks

EDIT: So I've found Thinktecture.IdentityModel.Client which contains a JwtClaimTypes that seems to mirror ClaimTypes. Why is this named with a Jwt prefix though?

Jarrett answered 30/7, 2015 at 11:52 Comment(1)
as pointed out by @ScottBrady in his commet the IdentityModel package can help you. Use IdentityModel.JwtClaimTypes.SubjectJobye
C
8

The IdentityServer ClaimType constants are just a map of the OpenID Connect standard claims.

You'd be best off making your own class for these constants, as you said there's no point pulling in the full Identity Server 3 package and I don't think they are available in any other packages...

Do note that the claims come across via JSON in the JWT as snake case. For example FamilyName will be family_name.

Cholula answered 1/8, 2015 at 17:10 Comment(4)
Cheers that's what I'm doing, just thought there must be a constants collection that's been placed in a client library? Maybe not!Jarrett
Check out the new/refactored IdentityModel package. Has a class that meets the OpenID Connect spec and also some JWT claims. github.com/IdentityModel/IdentityModel/blob/master/source/…Cholula
I'm confused because the lists in the two links do not match. I double checked I'm looking at the latest version of each. There are some that exist in Constants.ClaimTypes that do not exist in the OpenID spec, such as Role. It doesn't seem like the open ID spec is really the source. What am I missing here?Trompe
@GregSmalter The source of truth for OIDC claim types would be the OIDC spec. Anything else in the IdentityServer codebase is likely custom to IdentityServer, but at least accepted by the community.Cholula
V
4

You can install the Microsoft.AspNetCore.Authentication.JwtBearer package. It includes the JwtRegisteredClaimNames struct which you can use like:

using static Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;
⋮
var userId = User.FindFirstValue(Sub);
Verbenaceous answered 8/2, 2020 at 19:42 Comment(0)
S
1

Agree with Scott Brady, the best way to go about this is to create your constants class. We have created a shared library for this purpose, which contains claim type constants and have used them both in the server and the client projects.

NB: Apart from 'id_token' and 'sub' claim types, you can use your custom claim types in the implementation of 'IUserService'. This gives better clarity to claim type names also as you can use specific names based on your implementation.

Sparke answered 5/8, 2015 at 9:19 Comment(0)
H
1

Use IdentityModel

I've seen people use bare strings like "sub", but why, when the constants exist?

namespace IdentityModel
{
  /// <summary>Commonly used claim types</summary>
  public static class JwtClaimTypes
  {
    /// <summary>Unique Identifier for the End-User at the Issuer.</summary>
    public const string Subject = "sub";
    /// <summary>End-User's full name in displayable form including all name parts, possibly including titles and suffixes, ordered according to the End-User's locale and preferences.</summary>
    public const string Name = "name";
    /// <summary>Given name(s) or first name(s) of the End-User. Note that in some cultures, people can have multiple given names; all can be present, with the names being separated by space characters.</summary>
    public const string GivenName = "given_name";
    /// <summary>Surname(s) or last name(s) of the End-User. Note that in some cultures, people can have multiple family names or no family name; all can be present, with the names being separated by space characters.</summary>
    public const string FamilyName = "family_name";
Humanoid answered 23/5, 2022 at 13:35 Comment(3)
Because it’s MaGiCJarrett
Using "sub" in many places in your code is by definition a magic string: deviq.com/antipatterns/magic-strings. This might be a slightly different case b/c the name sub will probably never change, but I still prefer to avoid reused bare strings as much as possible. It's just a good practice for me to stay in. I think that is why Visual Studio formats bare strings in red. Anyway, reasonable people will have a difference of opinion and that is OK. I hope you have a great day :DHumanoid
Also as you can see in this answer, the name is documented. Using "sub" in your code is not documented and could be confusing for junior developers. You avoid typos and any good IDE will show the value when you hover over the constant.Humanoid

© 2022 - 2024 — McMap. All rights reserved.