2

I've spent some time getting my MVC 6 .NET Core website working with Azure B2C and everything seems to be working great. However, there are a few questions surrounding claims that I can't seem to figure out the correct strategy.

Say a user signs up on my site with email, firstname, lastname. Once the registration is complete, I would like to add a record into a UserProfile table in my database that references this user.

Question 1: Should I create a "UserProfileId" claim in Azure B2C? Or should I create an "ObjectId" field in my database table that references the AD user? What would make more sense?

Question 2: Once a user registers, where and how would I update an AD User claim? Would I do it in one of these events? Or somewhere else? I see there is a "User is new" claim that I could check for?

OnAuthenticationValidated
OnAuthorizationCodeReceived
OnRedirectToAuthenticationEndpoint

Question 3: To update the claims, would I use: Microsoft.Azure.ActiveDirectory.GraphClient? Does anyone have any sample code for how to update a custom claim? I've tried this but it doesn't seem to persist:

var identity = context.AuthenticationTicket.Principal.Identity as ClaimsIdentity;
identity?.AddClaim(new Claim("EmployeeId", "33"));

Here is my authentication configuration. Thanks!!!!!

public void ConfigureAuth(IApplicationBuilder app, IOptions<PolicySettings> policySettings, AuthenticationHelper authHelper)
{
    app.UseCookieAuthentication(options =>
    {
        options.AutomaticAuthenticate = true;
        options.AutomaticChallenge = true;
        options.AccessDeniedPath = "/Home/Forbidden";
        options.CookieSecure = CookieSecureOption.Always;
        options.ExpireTimeSpan = TimeSpan.FromHours(1);
        options.SlidingExpiration = true;
    });

    app.UseOpenIdConnectAuthentication(options =>
    {
        options.PostLogoutRedirectUri = policySettings.Value.PostLogoutRedirectUri;
        options.AutomaticAuthenticate = true;
        options.AutomaticChallenge = true;
        options.ClientId = policySettings.Value.ClientId;
        options.CallbackPath = new PathString("/signin-mysite");
        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("email");
        options.ResponseType = OpenIdConnectResponseTypes.IdToken;
        options.Authority = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", policySettings.Value.AadInstance, policySettings.Value.Tenant);
        options.Events = new OpenIdConnectEvents {
            OnAuthenticationValidated = OnAuthenticationValidated,
            OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
            OnAuthenticationFailed = OnAuthenticationFailed,
            OnRedirectToAuthenticationEndpoint = OnRedirectToAuthenticationEndpoint
        };
        options.ConfigurationManager = new PolicyConfigurationManager(
            String.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}", policySettings.Value.AadInstance, policySettings.Value.Tenant, "v2.0", OpenIdProviderMetadataNames.Discovery),
            new string[] { policySettings.Value.SignUpInPolicyId, policySettings.Value.ProfilePolicyId, policySettings.Value.PasswordPolicyId });
    });
}
Community
  • 1
  • 1
Primico
  • 2,143
  • 3
  • 24
  • 36

2 Answers2

1

Question 1: Should I create a "UserProfileId" claim in Azure B2C? Or should I create an "ObjectId" field in my database table that references the AD user? What would make more sense?

1a - I didn't add anything to the B2C tenant.

1b - I take the object id from B2C and store it in my table as an alternate key. My table has a unique id of it's own. Should I ever wish to have additional identity providers, this will be necessary.

I only use the object id from B2C to look up users and get my own id.

Question 2: Once a user registers, where and how would I update an AD User claim? Would I do it in one of these events? Or somewhere else? I see there is a "User is new" claim that I could check for?

When you say "update the claim" do you mean update permanently in the B2C tenant, or do you mean add it to the other claims and use it temporarily during the life of this particular token?

There's no connection back to B2C without using the graph client.

The userIsNew claim comes from B2C one time and only at the end of the signup process. You use that to determine if you have a new user trying to access your system. I hook that to create new entries in my tables from the claims that B2C gives me and from then on, the claims all come from the information in my tables.

Question 3: To update the claims, would I use: Microsoft.Azure.ActiveDirectory.GraphClient? Does anyone have any sample code for how to update a custom claim? I've tried this but it doesn't seem to persist:

I have to ask the "update" question again.

What you may be looking for is to "transform" the claims. That's usually done during a TicketReceived event for cookies. That occurs when they have authenticated for the first time. (Not to be confused with signing up.)

I'm not all that bright, but I'll tell you that I spent waaaay too much time on this trying to get it right. Mostly it's because there are a vast number of options and no one can tell you all the right ones for your project. So you just see reams of information that you have go through to find the bits you want.

I found this book (and it's author) incredibly helpful. It's current and he's a Microsoft guy who writes really well.

HTH

Bill Noel
  • 1,120
  • 9
  • 21
0

Regarding question 1: I did the same as nhwilly: I store the additional information in my database.

Regarding question 2: you can add claims in the OnsigningIn event:

app.UseCookieAuthentication(new Microsoft.AspNetCore.Builder.CookieAuthenticationOptions()
        {
            Events = new CookieAuthenticationEvents()
            {
                OnSigningIn = (context) =>
                {
                    ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
                    identity.AddClaim(new Claim("sb:tID", "555"));
                    return Task.FromResult(0);
                }
            }
        });

I got the information from Transforming Open Id Connect claims in ASP.Net Core.

Regarding question 3: I haven't done it myself, but this link should get you kickstarted: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet

Hope that helps!

Community
  • 1
  • 1