简体   繁体   中英

Get traffic returned from social login providers to create a local account on my .net core 2.2 web app

I've always used a mix of home baked plus 3rd party packages to accomplish social logins (Google, Facebook, and Twitter specifically). With me in full control, I could specify the return method and then capture the response data from the social provider, map the fields I wanted (name, email address, and 3rd party ID) to my own local model to create a local user account and then specify what type of account that is (admin, regular user etc).

With .net core 2.2, everything seems to happen behind the scenes and I can't figure out how to capture the traffic when it comes back after the call to /me for example in facebook. That behind the scenes call returns a JSON response that my local app is then mapping to the claims to log me in. That's all great, but I also want to capture that data and create a local user account in my own data store.

I can see it all happening in fiddler so I know it's still doing the work, I just don't know how to tap into it to extract what I need at that stage during the process. Sticking with facebook for my example here, I thought I could change the facebookOptions.CallbackPath property in my startup.cs file, then add that callback as an accepted callback in the facebook app, wire up a method on a controller that matches that path and get the data from there. I'd be ok with having the work out the rest of the process by hand, but all that did was move the behind the scenes work that .net core is doing to that "location".

I suppose I could just do a check every time a user hits a page on the site when they're authenticated to see if I need to add or update their local session, but that seems overly ghetto to me. I want to be able to do this once per session as soon as they log in. I'll be the first to admit that my skills with Identity are pretty weak so maybe I'm missing something there?

any guidance or suggestions would be greatly appreciated.

TIA

I figured out a way to do this but I"m not sure if this is the best approach or not. I created a helper class with a static method that I invoke inside of the Options.Events.OnCreatingTicket event inside my AddAuthentication() inside startup.cs.

From here, I can loop over my claims list, save the user to my local datastore and either create or update local user information.

If this is not the best way to handle this, I'd love some better direction.

TIA

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
                options =>
                {
                    options.LoginPath = new PathString("/account");
                })
            .AddFacebook(facebookOptions =>
                {
                    facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
                    facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
                    facebookOptions.CallbackPath = new PathString("/account/facebook");
                    facebookOptions.Events.OnCreatingTicket = ctx =>
                    {
                        ExternalLoginProviderHelper.LoginLocally(ctx.Principal);
                        return Task.CompletedTask;
                    };
                })
            .AddGoogle(options =>
                {
                    options.ClientId = Configuration["Authentication:Google:ClientId"];
                    options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
                    options.Events.OnCreatingTicket = ctx =>
                    {
                        ExternalLoginProviderHelper.LoginLocally(ctx.Principal);
                        return Task.CompletedTask;
                    };
        });

and my helper class:

public class ExternalLoginProviderHelper
{
    public static void LoginLocally(ClaimsPrincipal claimsPrincipal)
    {
        foreach(Claim claim in claimsPrincipal.Claims)
        {
            // extract the claim information here (ID, Email address, name (surname, given name) etc)
            // make repository call to save information to the datastore and get a local user ID
        }
        // also set other claims for local user id, user type (admin, regular user) etc.
        ClaimsIdentity claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity;
        claimsIdentity.AddClaim(new Claim("usertype", "admin")); // this is just an example N/V pair
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM