0

I'm trying to have a user sign in with local account and then sign up with a social account so that I can link the two together in my own database. That way, later they could use B2C and login with either local or social providers and end up with the same account in my system.

The trick seems to be securely communicating information from the signed in local user (like my database id for that user) to the sign up process for the social provider so that it can come back in the claims for the new user.

I thought about adding it to the RedirectUrl of the AuthenticationOptions but I can't work out how insecure that might be. If that endpoint was protected by an [Authorize] attribute, then a user would have to be authenticated before calling it.

It seems like it wouldn't be safe to add the database id of the local user into the redirect. Even though the user would be authenticated, a stolen token and a modified query string would like the wrong accounts.

Is there a way to make data roundtrip through the B2C process?

{EDIT} Forgot to mention this is a web app. Native client I understand how to save the token.

Bill Noel
  • 1,120
  • 9
  • 21

1 Answers1

1

OK, in case this helps anyone else trying to do this...

You need to secure the controller action with an [Authorize] attribute . That way the incoming claims will be present after authenticating with the B2C signup policy for the external identity provider (e.g. Facebook).

In OpenIdconnectionOptions for that policy, specify an event handler,

Events = new OpenIdConnectEvents
    {
    ...
    OnTicketReceived = TicketReceived,
    ...
    }

And then in the method:

private Task TicketReceived(TicketReceivedContext context)
 {
     var incomingClaims = context
         .HttpContext
         .User
         .Identities
         .First()
         .Claims;

     var newClaims = context
         .Principal
         .Identities
         .First()
         .Claims;

     context
        .Principal
        .Identities
        .First()
        .AddClaim(new System.Security.Claims.Claim("myClaim", "myClaimValue"));
 }

The incomingClaims contain the information from the user that was logged in when they decided to add the new provider, and the newClaims are those from the signup they just completed.

Now you can do whatever magic you want to connect the two in your own db.

HTH

Bill Noel
  • 1,120
  • 9
  • 21
  • I had some difficulty with the system assuming that you were already logged in before redirecting to the social provider. I changed the policy for that social sign up to disable single sign-on configuration and that seemed to fix it. – Bill Noel Mar 27 '17 at 14:18
  • Ok, no. That doesn't work. You have to create a new principal to actually update the claims. – Bill Noel Apr 15 '17 at 23:32