15

Why do I want this?

I'm trying to get a unique identifier from my user which I can connect to database records. There are reasons I don't want to use the Email as the identifier. I read that SUB claim isn't supported with B2C, and to use OID in it's place.

Steps I've Taken

So, I've set up that both of my policies return Object ID on Azure B2C:

enter image description here

I'm using individual SignIn and SignUp policies at the moment, and I get all of the claims back, including the email claim which I specified I wanted to be returned. I cannot however find a claim related to OID or SUB.

User.Claims 

Nets me the following results:

enter image description here

The single breadcrumb of hope that I have found is this claim:

Type: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

Value: Not supported currently. Use oid claim.

Questions

Have I missed some additional step that you need to perform to retrieve this particular claim?

Has anyone had any success retrieving an OID or SUB from Azure B2C?

David Moores
  • 1,025
  • 2
  • 9
  • 23

5 Answers5

23

Well, this is embarrassing, I must have looked over this line about 30 times and not noticed...

I was retrieving the OID token, it's claim type was:

http://schemas.microsoft.com/identity/claims/objectidentifier

As can be clearly seen in my provided screenshots. I'll leave this question up as, the schema may throw someone else off.

David Moores
  • 1,025
  • 2
  • 9
  • 23
  • 1
    The http://schemas.microsoft.com/identity/claims/objectidentifier type is coming from thee parsing libraries that maps them. Its possible to clear these mappings in the startup to avoid those anoyting things :) – Poul K. Sørensen Mar 17 '17 at 15:51
  • I had the same issue, except I didn't set the claims. I noted that the `nameidentity` claim had a guid that matched the object id of the claim. – Justin Dearing Feb 23 '18 at 21:54
  • 1
    The answer to the question was a link, the link is what the library used for the claim type. As can be seen in the screenshot, there are three claim types whose value is a URL.Think of it like an XML schema where you would often define a namespace as a URL - it makes it unique – David Moores Mar 29 '19 at 12:59
15

If you are using the Microsoft.Identity.Web package there is now a ClaimsPrincipalExtensions class that provides an extension method, so that you can simply use:

// using Microsoft.Identity.Web;

User.GetObjectId();

This uses the oid or http://schemas.microsoft.com/identity/claims/objectidentifier claim.

M-Peror
  • 712
  • 8
  • 16
12

I struggled with this for a little while and this post helped me.

To update things with some code, the below will obtain the object identifier value (unique user id in Azure)

User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value

Thanks for pointing out the differences in the schema/types!

Coy Meeks
  • 700
  • 9
  • 10
2

Since the links above are broken and this is something that I really struggled to find a working example of, here is a code fragment of what I ended up using;

using System.IdentityModel.Tokens.Jwt;
...
string oid;
string pTokenInput = Request.Headers["x-ms-token-aad-id-token"].ToString();
var lJWTHandler = new JwtSecurityTokenHandler();
if (lJWTHandler.CanReadToken(pTokenInput)
{
    var lToken = lJWTHandler.ReadJwtToken(pTokenInput);
    if (lToken.Payload.ContainsKey("oid"))
        oid = lToken.Payload["oid"].ToString();
}

Hopefully, this will help someone else...

Jay13
  • 860
  • 9
  • 15
1

It seems that you do not necessarily need object-identifier here. When debugging, I see that the value of object-identifier is mapped to nameidentifier enter image description here

Which is accessible with the built-in constant NameIdentifier:

var identity = authState.User.Identity as System.Security.Claims.ClaimsIdentity;
var userId = identity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier).Value;
Sven
  • 2,345
  • 2
  • 21
  • 43