将Google idToken交换为本地openId令牌C# [英] Exchanging a google idToken for local openId token c#

查看:145
本文介绍了将Google idToken交换为本地openId令牌C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用这个github项目 https://github.com/openiddict/openiddict-core太好了.但是,当用户使用外部身份提供程序时,我对于程序应该是什么或如何实现这些程序感到困惑,例如,在本例中,我将使用google.

I am using this github project https://github.com/openiddict/openiddict-core which is great. But I am stuck as to what the procedures should be, or how to implement them, when the user uses an external identity provider, for this example, I will use google.

我正在运行一个带有aspnet核心webAPI的angular2应用程序.我所有的本地登录均正常运行,我使用用户名和密码呼叫connect/token,并返回了accessToken.

I have an angular2 app running, with an aspnet core webAPI. All my local logins work perfectly, I call connect/token with a username and password, and an accessToken is returned.

现在,我需要将google实施为外部身份提供商.我已按照此处的所有步骤实施Google登录按钮.用户登录时会打开一个弹出窗口.这是我为Google按钮创建的代码.

Now I need to implement google as an external identity provider. I have followed all the steps here to implement a google login button. This opens a popup when the user logins in. This is the code I have created for my google button.

// 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
}

现在我有一个来自Google的idToken.在此处上找到的Google页面的下一步说,我需要验证我可以执行的google accessToken,但是如何交换我从google获得的accessToken,并创建可在我的应用程序中使用的本地accessToken?

Now I have an idToken from google. The next step on the google pages found here says that I need to validate the google accessToken, which I can do, but how do I exchange the accessToken that I have from google, and create local accessToken which can be used on my application?

推荐答案

在这里找到的google页面的下一步说,我需要验证google accessToken,我可以这样做,但是我该如何交换我从google获得的accessToken,并创建可以在我的Google上使用的本地accessToken.申请吗?

The next step on the google pages found here says that i need to validate the google accessToken, which i can do, but how do i exchange the accessToken that i have from google, and create local accessToken which can be used on my application?

您尝试实现的流程称为断言授予.您可以阅读其他SO帖子以获取更多信息.

The flow you're trying to implement is known as assertion grant. You can read this other SO post for more information about it.

OpenIddict完全支持自定义授予,因此您可以在令牌终结点操作中轻松实现这一点:

OpenIddict fully supports custom grants, so this is something you can easily implement in your token endpoint action:

[HttpPost("~/connect/token")]
[Produces("application/json")]
public IActionResult Exchange()
{
    var request = HttpContext.GetOpenIdConnectRequest();
    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服务器选项中启用它:

Note that you'll also have to enable it in the OpenIddict server options:

services.AddOpenIddict()
    // ...

    .AddServer(options =>
    {
        options.AllowCustomFlow("urn:ietf:params:oauth:grant-type:google_identity_token");
    });

在发送令牌请求时,请确保使用正确的grant_type并将id_token作为assertion参数发送,它应该可以工作.这是Postman的示例(适用于Facebook访问令牌,但其工作方式完全相同):

When sending a token request, make sure to use the right grant_type and to send your id_token as the assertion parameter, and it should work. Here's an example with Postman (for Facebook access tokens, but it works exactly the same way):

也就是说,在实施令牌验证例程时,您必须非常小心,因为此步骤特别容易出错.验证包括观众在内的所有内容非常重要(否则,您的服务器会容易受到混乱的副手攻击).

That said, you have to be extremely careful when implementing the token validation routine, as this step is particularly error-prone. It's really important to validate everything, including the audience (otherwise, your server would be vulnerable to confused deputy attacks).

这篇关于将Google idToken交换为本地openId令牌C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆