资源所有者密码授予和Google身份验证

资源所有者密码授予和Google身份验证

本文介绍了Identity Server 4-资源所有者密码授予和Google身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,当前使用资源所有者密码授予类型来允许用户通过单页应用程序登录.身份服务器当前与Web API托管在同一项目中.但是,我们想为用户添加使用其Google帐户注册/登录的功能.当前,用户数据存储在表中,并由ASP.NET Core Identity管理.

I have an application that currently uses the resource owner password grant type to allow users to log in via a single page application. The identity server is hosted in the same project as the Web API currently. However, we would like to add the ability for a user to register / log in using their Google account. Currently, the user data is stored in tables and managed by ASP.NET Core Identity.

有没有一种方法可以使应用程序中的资源所有者密码授予类型既适用于本地"用户,又可以通过Google启用第三方身份验证?当前,我们使用用户名和密码访问Identity Server令牌端点,并将令牌存储在浏览器中.然后将其传递到任何需要授权的端点.集成Google身份验证和检索Google令牌时,同样的流程是否仍然有效?

Is there a way to have both the resource owner password grant type available in the application for users who are 'local' but also enable third party authentication via Google? Currently, we hit the Identity Server token endpoint with a username and password and store the token in the browser. It's then passed to any endpoint that requires authorization. Would this same flow still work when integrating Google authentication and retrieving the Google token?

推荐答案

所有功劳归于 Behrooz Dalvandi ,用于了不起的帖子.

All the credit goes to Behrooz Dalvandi for this amazing post.

解决此问题的方法是创建一个自定义授予并实现IExtensionGrantValidator.

The solution to this problem is to create a custom grant and implement IExtensionGrantValidator.

public class GoogleGrant : IExtensionGrantValidator
{
    private readonly IGoogleService _googleService;
    private readonly IAccountService _accountService;

    public GoogleGrant(IGoogleService googleService, IAccountService accountService)
    {
        _googleService = googleService;
        _accountService = accountService;
    }
    public string GrantType
    {
        get
        {
            return "google_auth";
        }
    }

    public async Task ValidateAsync(ExtensionGrantValidationContext context)
    {
        var userToken = context.Request.Raw.Get("id_token");

        if (string.IsNullOrEmpty(userToken))
        {
            //You may want to add some claims here.
            context.Result = new GrantValidationResult(TokenErrors.InvalidGrant, null);
            return;
        }
        //Validate ID token
        GoogleJsonWebSignature.Payload idTokenData = await _googleService.ParseGoogleIdToken(userToken);

        if (idTokenData != null)
        {
            //Get user from the database.
            ApplicationUser user = await _accountService.FindByEmail(idTokenData.Email);

            if(user != null)
            {
                context.Result = new GrantValidationResult(user.Id, "google");
                return;
            }
            else
            {
                return;
            }

        }
        else
        {
            return;
        }
    }
}

在启动中配置此验证器

            var builder = services.AddIdentityServer()
            .AddInMemoryIdentityResources(Config.Ids)
            .AddInMemoryApiResources(Config.Apis)
            .AddInMemoryClients(Config.Clients)
            .AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>()
            .AddExtensionGrantValidator<GoogleGrant>();//Custom validator.

最后但并非最不重要的一点.在配置文件中添加以下代码.注意"google_auth"授权类型.

And last but not the least.Add below code in the config file. Notice the 'google_auth' grant type.

new Client
            {
                ClientId = "resourceownerclient",

                AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials.Append("google_auth").ToList(),
                AccessTokenType = AccessTokenType.Jwt,
                AccessTokenLifetime = 3600,
                IdentityTokenLifetime = 3600,
                UpdateAccessTokenClaimsOnRefresh = true,
                SlidingRefreshTokenLifetime = 30,
                AllowOfflineAccess = true,
                RefreshTokenExpiration = TokenExpiration.Absolute,
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                AlwaysSendClientClaims = true,
                Enabled = true,
                ClientSecrets=  new List<Secret> { new Secret("dataEventRecordsSecret".Sha256()) },
                AllowedScopes = {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerConstants.StandardScopes.OfflineAccess,
                    "api1"
                }
            }

这篇关于Identity Server 4-资源所有者密码授予和Google身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 11:26