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

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

问题描述

我正在使用这个 github 项目

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

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.

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.

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
}

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?

解决方案

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?

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 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."
    });
}

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");
    });

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天全站免登陆