我想知道同样的事情,但在网上找不到任何答案,所以我克隆了Microsoft.AspNetCore.Security (v2.1) repo,看看我是否能弄清楚它是如何工作的。我相信这就是您正在寻找的。将此添加到 Startup.cs 文件中的 ConfigureServices 方法中。
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(o => o.LoginPath = new PathString("/login"))
// You must first create an app with Google and add its ID and Secret to your user-secrets.
// https://console.developers.google.com/project
.AddGoogle(o =>
{
o.ClientId = "YOUR_GOOGLE_CLIENT_ID";
o.ClientSecret = "YOUR_GOOGLE_CLIENT_SECRET";
o.AuthorizationEndpoint += "?prompt=consent"; // Hack so we always get a refresh token, it only comes on the first authorization response
o.AccessType = "offline";
o.SaveTokens = true;
o.Events = new OAuthEvents()
{
// There are a number of (optional) events you may want to connect into and add your own claims to the user, or handle a remote failure, etc.
OnRemoteFailure = HandleOnRemoteFailure,
OnCreatingTicket = HandleOnCreatingTicket
};
o.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url");
});
如果您想拦截某些事件以向用户添加额外的声明,或者将它们存储在数据库中以应用应用级授权,您可以连接到各种OAuthEvents。我将以下方法放在 Startup.cs 文件的底部,在 Startup 类中。
private async Task HandleOnCreatingTicket(OAuthCreatingTicketContext context)
{
var user = context.Identity;
// please use better logic than GivenName. Demonstration purposes only.
if(user.Claims.FirstOrDefault(m=>m.Type==ClaimTypes.GivenName).Value == "MY_FAVORITE_USER")
{
user.AddClaim(new Claim(ClaimTypes.Role, "Administrator"));
}
await Task.CompletedTask;
}
private async Task HandleOnRemoteFailure(RemoteFailureContext context)
{
// add your logic here.
await Task.CompletedTask;
}
最后,您需要添加几个控制器操作。我把我的放在一个 AccountController.cs 文件中,如下所示:
public class AccountController : Controller
{
[AllowAnonymous]
[Route("/login")]
public async Task<IActionResult> Login()
{
if (User == null || !User.Identities.Any(identity => identity.IsAuthenticated))
{
// By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo),
// send them to the home page instead (/).
string returnUrl = HttpContext.Request.Query["ReturnUrl"];
returnUrl = string.IsNullOrEmpty(returnUrl) ? "/" : returnUrl;
await HttpContext.ChallengeAsync("Google", new AuthenticationProperties() { RedirectUri = returnUrl });
}
return View();
}
[Authorize]
[Route("/logout")]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme, new AuthenticationProperties() { RedirectUri="/" });
return View();
}
}
我还放置了几个简单的视图,以便用户在注销后可以单击链接返回主页,或再次登录或以其他用户身份登录,等等。
这似乎对我有用。