不要使用 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();
}
我们正在使用 .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();
}