不要使用 Google 登录存储主体

Don't store principal with Google login

我们正在使用 .NET Core 3.1 和 Google 身份验证。这是我们目前拥有的代码:

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();
    }
}

当用户访问 /Account/SignInGoogle 时,他们将被重定向到 Google 登录页面。一旦他们成功登录,他们将被重定向回 /Account/SignInReturn。如果我在那里放置一个断点,我可以看到在 User 属性.

中设置了声明

我们是否可能以某种方式在 SignInReturn 中接收用户信息(名字、姓氏、电子邮件),而没有在 User 字段中设置用户主体?我们不希望 Google 中间件执行实际登录(设置 User 主体)。我们只想验证用户是否能够登录他们的公司 Google 帐户,然后在我们收到他们用于登录的电子邮件后继续自定义登录逻辑。

SignInReturn动作中接收到用户后,就可以轻松实现自定义登录,甚至注销用户,比如下面的代码:

 await HttpContext.SignOutAsync();

或者要接收用户信息,请执行以下操作并在必要的检查后重新登录:

[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();
}