Home > Blockchain >  Don't store principal with Google login
Don't store principal with Google login

Time:04-24

We are using .NET Core 3.1 and Google Authentication. This is the code that we have currently:

Startup.cs:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddGoogle(googleOptions =>
    {
        googleOptions.ClientId = "CLIENT_ID"
        googleOptions.ClientSecret = "CLIENT_SECRET"
    })
    .AddCookie(options =>
    {
        options.LoginPath = "/Account/Login";
        options.AccessDeniedPath = "/Error/403";
    });

AccountController.cs:

public class AccountController : BaseController
{
    [AllowAnonymous]
    public IActionResult SignInGoogle()
    {
        return Challenge(new AuthenticationProperties
        {
            RedirectUri = Url.Action(nameof(SignInReturn))
        }, GoogleDefaults.AuthenticationScheme);
    }

    [AllowAnonymous]
    public IActionResult SignInReturn()
    {
        // User's information is in the User property of the controller. We don't want that.
        return Ok();
    }
}

When users visit /Account/SignInGoogle, they are redirected to Google sign in page. Once they log in successfully, they are redirected back to /Account/SignInReturn. If I place a breakpoint there, I can see that claims are set inside User property.

Is it possible that we somehow receive user information (name, surname, email) in SignInReturn without the user principal being set in User field? We don't want Google middleware to perform the actual log in (setting User principal). We just want to verify that users are able to sign in to their company Google account and then proceed with custom login logic once we receive the email that they used to sign in.

CodePudding user response:

After receiving the user in SignInReturn action, you can easily implement your custom login, even logout the user, such as the following code:

 await HttpContext.SignOutAsync();

Or to receive user information, do the following and sign in again after the necessary checks:

[AllowAnonymous]
public async Task<IActionResult> SignInReturn()
{
   var authenticateResult = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);

   if (!authenticateResult.Succeeded)
   {
       return Unauthorized();
   }

   string email = authenticateResult.Principal?.FindFirst(s => s.Type == ClaimTypes.Email)?.Value;

   string giveName = authenticateResult.Principal?.FindFirst(s => s.Type == ClaimTypes.GivenName)?.Value;

   string surName = authenticateResult.Principal?.FindFirst(s => s.Type == ClaimTypes.Surname)?.Value;

   string fullName = authenticateResult.Principal?.FindFirst(s => s.Type == ClaimTypes.Name)?.Value;

   //Check the user exist in the database by email or other items, and signin the user again
   //await HttpContext.SignInAsync();
}
  • Related