有没有办法在没有 ASP.NET 身份的情况下通过谷歌在核心中实现身份验证 ASP.Net? 我已经实现了基于 cookie 的身份验证,如下所示:
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x
我需要将谷歌身份验证添加到项目中。
当然是的。以下是您可以解决此问题的一种方法的摘要。
可以直接调用 OAuth2 身份验证服务器 API,并在 .NET 中编写自定义属性/处理程序/筛选器以与该功能集成并相应地控制对资源的访问。
https://developers.google.com/identity/protocols/OAuth2WebServer
我相信Google为其显式授权/服务器身份验证流程提供的当前端点如下:
- 登录: https://accounts.google.com/o/oauth2/v2/auth
- 代币:https://www.googleapis.com/oauth2/v4/token
- 详细信息:https://www.googleapis.com/plus/v1/people/me
您可以在上面的链接中找到有关特定HTTP请求和响应的更多详细信息,但据我了解,这是Web服务器OAuth2的一般要点:)
回到核心应用程序,然后可以编写自定义处理程序/过滤器/属性代码来处理身份验证和重定向。可以在此处找到一些示例 .NET 核心代码:
https://ignas.me/tech/custom-authentication-asp-net-core-20/
我想知道同样的事情,但在网上找不到任何答案,所以我克隆了Microsoft.AspNetCore.Security (v2.1)
存储库,看看我是否可以弄清楚它是如何工作的。我相信这就是你要找的。将其添加到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();
}
}
我还放了几个简单的视图,以便一旦注销,用户可以单击链接返回主页,或再次登录或以其他用户身份登录等。
这似乎对我有用。