将google idToken替换为本地openId令牌c#
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将google idToken替换为本地openId令牌c#相关的知识,希望对你有一定的参考价值。
我正在使用这个github项目https://github.com/openiddict/openiddict-core这很棒。但是,当用户使用外部身份提供商时,我会被困在程序应该是什么,或者如何实现它们,对于这个例子,我将使用谷歌。
我有一个angular2 app运行,带有aspnet核心webAPI。我所有的本地登录工作都很完美,我用connect/token
用户名和密码调用,然后返回一个accessToken。
现在我需要将谷歌作为外部身份提供商实施。我已按照所有步骤here实施谷歌登录按钮。这会在用户登录时打开一个弹出窗口。这是我为google按钮创建的代码。
// Angular hook that allows for interaction with elements inserted by the
// rendering of a view.
ngAfterViewInit() {
// check if the google client id is in the pages meta tags
if (document.querySelector("meta[name='google-signin-client_id']")) {
// Converts the Google login button stub to an actual button.
gapi.signin2.render(
'google-login-button',
{
"onSuccess": this.onGoogleLoginSuccess,
"scope": "profile",
"theme": "dark"
});
}
}
onGoogleLoginSuccess(loggedInUser) {
let idToken = loggedInUser.getAuthResponse().id_token;
// here i can pass the idToken up to my server and validate it
}
现在我有来自谷歌的idToken。在谷歌页面的下一步发现here说我需要验证谷歌accessToken,我可以做,但我如何交换谷歌的accessToken,并创建可以在我的应用程序上使用的本地accessToken?
在这里找到的google页面的下一步说我需要验证google accessToken,我可以这样做,但是我如何从google交换accessToken,并创建可以在我的应用程序上使用的本地accessToken?
您尝试实现的流程称为断言授权。你可以阅读this other SO post for more information。
OpenIddict完全支持自定义授权,因此您可以在令牌端点操作中轻松实现这一点:
[HttpPost("~/connect/token")]
[Produces("application/json")]
public IActionResult Exchange(OpenIdConnectRequest request)
{
if (request.IsPasswordGrantType())
{
// ...
}
else if (request.GrantType == "urn:ietf:params:oauth:grant-type:google_identity_token")
{
// Reject the request if the "assertion" parameter is missing.
if (string.IsNullOrEmpty(request.Assertion))
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidRequest,
ErrorDescription = "The mandatory 'assertion' parameter was missing."
});
}
// Create a new ClaimsIdentity containing the claims that
// will be used to create an id_token and/or an access token.
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
// Manually validate the identity token issued by Google,
// including the issuer, the signature and the audience.
// Then, copy the claims you need to the "identity" instance.
// Create a new authentication ticket holding the user identity.
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
OpenIdConnectServerDefaults.AuthenticationScheme);
ticket.SetScopes(
OpenIdConnectConstants.Scopes.OpenId,
OpenIdConnectConstants.Scopes.OfflineAccess);
return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
}
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.UnsupportedGrantType,
ErrorDescription = "The specified grant type is not supported."
});
}
请注意,您还必须在OpenIddict选项中启用它:
// Register the OpenIddict services, including the default Entity Framework stores.
services.AddOpenIddict()
// Register the Entity Framework stores.
.AddEntityFrameworkCoreStores<ApplicationDbContext>()
// Register the ASP.NET Core MVC binder used by OpenIddict.
// Note: if you don't call this method, you won't be able to
// bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
.AddMvcBinders()
// Enable the token endpoint.
.EnableTokenEndpoint("/connect/token")
// Enable the password flow, the refresh
// token flow and a custom grant type.
.AllowPasswordFlow()
.AllowRefreshTokenFlow()
.AllowCustomFlow("urn:ietf:params:oauth:grant-type:google_identity_token")
// During development, you can disable the HTTPS requirement.
.DisableHttpsRequirement();
发送令牌请求时,请确保使用正确的grant_type
并将您的id_token作为assertion
参数发送,它应该可以正常工作。这是Postman的一个例子(对于Facebook访问令牌,但它的工作原理完全相同):
也就是说,在实现令牌验证例程时必须非常小心,因为此步骤特别容易出错。验证所有内容非常重要,包括观众(否则,your server would be vulnerable to confused deputy attacks)。
以上是关于将google idToken替换为本地openId令牌c#的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 express-Jwt 解码来自 idToken 的信息?
如何从 Expo GoogleSignIn API (expo v32) 获取 idToken?
java.lang.IllegalArgumentException:必须指定 idToken 或 accessToken