将google idToken替换为本地openId令牌c#

我正在使用这个github项目https://github.com/openiddict/openiddict-core这很棒。 但是,当用户使用外部身份提供商时,我会被困在程序应该是什么,或者如何实现它们,对于这个例子,我将使用谷歌。

我有一个angular2 app运行,带有aspnet核心webAPI。 我的所有本地登录工作都很完美,我使用用户名和密码调用connect/token ,并返回accessToken。

现在我需要将谷歌作为外部身份提供商实施。 我已按照此处的所有步骤实施Google登录按钮。 这会在用户登录时打开一个弹出窗口。这是我为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。 在这里找到的谷歌页面上的下一步说我需要validation谷歌accessToken,我可以做,但我如何交换谷歌的accessToken,并创建可以在我的应用程序上使用的本地accessToken?

在这里找到谷歌页面的下一步说我需要validation谷歌accessToken,我可以做,但我如何交换谷歌的accessToken,并创建可以在我的应用程序上使用的本地accessToken?

您尝试实现的流程称为断言授权 。 您可以阅读此其他SOpost以获取更多相关信息 。

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() // 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访问令牌,但它的工作原理完全相同):

在此处输入图像描述

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