Press Ctrl / CMD + C to copy this to your clipboard.
This post will be reported to the moderators as potential spam to be looked at
I'm trying to migrate from Umbraco 8.x to 9.0.1. All works fine, except the external backoffice authentication (Azure B2C). In this case I want to login using Azure AD B2C (which currencly has local accounts, and Azure AD. In the future there will be more options).
The old implementation of the external login was quite different (based on https://24days.in/umbraco-cms/2019/aad-and-headless/umbraco8-aadb2c/)
I try to simplify this implementation by using the build in external login providers (https://our.umbraco.com/documentation/reference/security/external-login-providers/).
My current setup let me authenticate against Azure AD B2C. The login works fine. The one thing is that after a succesful login, Umbraco says the email claim is missing:
The implementation I used came from https://our.umbraco.com/documentation/reference/security/auto-linking/
I tried to hook into OnAutoLinking and OnExternalLogin, but this seems not to be called yet (https://our.umbraco.com/documentation/reference/security/auto-linking/#transfering-claims-from-external-identities).
When I take a look at the claims that are returned, I do have an 'emails' claim. I do not have the 'email' claim. I would like to use the value from 'emails' for linking the accounts.
How can I get this account linking to work?
This specific issue is resolved by adding the claim after the external authentication occurs.
Remark: this is not in production yet. You might need some null checks for example. Also I'm not sure if this will work for every identity providering configured in your B2C tenant.
private static Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext ctx)
// This is where we appear after a successfull login, since we use AADB2C Open ID Connect, we already get a lot with the initial authorization code
ctx.Options.Events.OnAuthorizationCodeReceived = async context =>
context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http:", "https:");
// Get the current claims
var claims = ctx.Principal?.Claims;
// Find the original JWT token
string jwtTokenFromIdentityProvider =
claims.Where(m => m.Type.Equals("idp_access_token", StringComparison.OrdinalIgnoreCase))
.Select(m => m.Value).FirstOrDefault();
// Resolve the token to a readable format
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(jwtTokenFromIdentityProvider);
var tokenFromIdentityProvider = (JwtSecurityToken)jsonToken;
// Get the principal name (so: the login email)
var principalName = tokenFromIdentityProvider.Claims.First(claim => claim.Type == "upn").Value;
// Define the new claim
var claimsToAdd = new List<Claim>
new Claim("email", principalName)
// Add the claim by adding a new ClaimsIdentity
var appIdentity = new ClaimsIdentity(claimsToAdd);
var user = ctx.Principal;
var identity = user.Identity as ClaimsIdentity;
var claim = (from c in user.Claims
where c.Type == "idp_access_token"
is working on a reply...
Write your reply to:
Image will be uploaded when post is submitted