如何解决.NET Core Google OAuth和其他提供商-我需要存储访问令牌吗?
我不清楚在此社交登录实现中是否需要存储和/或使用访问令牌。
我可以通过如下配置Startup.cs来读取访问令牌。我知道在许多OAuth流中,访问令牌在使用前都会得到验证。
但是,我不确定使用.NET Core的身份验证框架为我完成了多少工作。我已经浏览了Microsoft.AspNetCore.Authentication.Google
来源,但这并没有使它变得更清晰。
在下面的LoginCallback
操作中,我可以使用以下方式为用户读取ID:
claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier));
据我所知,这就是我所需要的。我可以将该标识符存储在数据库中,如果该ID下一次与他们通过身份验证提供程序(Google,Facebook等)登录时匹配,则该用户可以再次登录。
这是提供了框架,但是在我读取该ID之前,该框架已经验证了访问令牌,这一点我不清楚。框架是否在设置AuthenticateResult
上的值之前验证了访问令牌,以便我可以相信它未被篡改?
如果是这样,我认为不需要存储访问令牌。
Startup.cs
services.AddAuthentication(o =>
{
o.DefaultScheme = "Application";
o.DefaultSignInScheme = "External";
})
.AddCookie("Application")
.AddCookie("External")
.AddGoogle(o =>
{
o.ClientId = "xxxxxxxxxxx";
o.ClientSecret = "xxxxxxxxxxx";
// Can access tokens by configuring as follows
o.SaveTokens = true;
o.Events.OnCreatingTicket = ctx =>
{
List<AuthenticationToken> tokens = ctx.Properties.GetTokens().ToList();
tokens.Add(new AuthenticationToken()
{
Name = "TicketCreated",Value = DateTime.UtcNow.ToString()
});
ctx.Properties.StoreTokens(tokens);
return Task.CompletedTask;
};
}) // Other providers ...
回调处理
[Route("oauth/google-challenge")]
public IActionResult GoogleLoginChallenge(string returnUrl)
{
return new ChallengeResult(
GoogleDefaults.AuthenticationScheme,new AuthenticationProperties
{
RedirectUri = Url.Action(nameof(LoginCallback),new { returnUrl,oauthProvider = OAuthProvider.Google })
});
}
[Route("oauth/facebook-challenge")]
public IActionResult FacebookLoginChallenge(string returnUrl)
{
return new ChallengeResult(
FacebookDefaults.AuthenticationScheme,oauthProvider = OAuthProvider.Facebook })
});
}
[Route("oauth/microsoft-challenge")]
public IActionResult MicrosoftLoginChallenge(string returnUrl)
{
return new ChallengeResult(
MicrosoftAccountDefaults.AuthenticationScheme,oauthProvider = OAuthProvider.MicrosoftAccount })
});
}
[Route("oauth/login-callback")]
public async Task<IActionResult> LoginCallback(string returnUrl,OAuthProvider oAuthProvider)
{
var authenticateResult = await HttpContext.AuthenticateAsync("External").ConfigureAwait(false);
if (!authenticateResult.Succeeded)
{
return BadRequest();
}
var claimsIdentity = new ClaimsIdentity("Application");
claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier));
claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.Email));
claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.Name));
foreach (KeyValuePair<string,string> item in authenticateResult.Properties.Items)
{
// Read access tokens here
}
foreach (KeyValuePair<string,string> item in authenticateResult.Ticket.Properties.Items)
{
// or here
}
string accessToken = await HttpContext.GetTokenAsync("access_token");
return Redirect(returnUrl);
}
解决方法
由于我不清楚该框架将采取什么措施来验证用户信息是否来自身份验证提供程序,因此我设置了来自.NET核心应用程序的请求以通过Fiddler。
"environmentVariables": {
...
"ALL_PROXY": "http://127.0.0.1:8888"
},
对于Google OAuth提供程序,在将浏览器重定向回signin-google
URI之后,我能够看到框架进行了以下调用:
www.googleapis.com/oauth2/v4/token
,发送客户端ID机密和其他信息以获得访问和ID令牌。
然后调用:
www.googleapis.com/oauth2/v4/userinfo
传递访问和ID令牌。
{
"id": "xxxx","email": "xxxx@xxxx.com","verified_email": true,"name": "Example","given_name": "Example","family_name": "Example","picture": "https://lh3.googleusercontent.com/a-/xxxxxx","locale": "en","hd": "xxxx.com"
}
很明显,令牌是短暂的,因此持久化令牌毫无意义。
通过在服务器之间使用服务器获取和验证访问令牌也很安全。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。