Identity Server 4 - 资源所有者密码授权和Google身份验证

3
我有一个应用程序,目前使用资源所有者密码授权类型,允许用户通过单页应用程序登录。身份服务器当前托管在与Web API相同的项目中。但是,我们希望添加用户可以使用其Google帐户注册/登录的功能。目前,用户数据存储在表中,并由ASP.NET Core Identity管理。
是否有一种方法可以在应用程序中同时提供资源所有者密码授权类型,以供“本地”用户使用,同时启用通过Google进行第三方身份验证?目前,我们使用用户名和密码命中Identity Server令牌端点,并在浏览器中存储令牌。然后将其传递到任何需要授权的终结点。当集成Google身份验证并检索Google令牌时,此流程是否仍然有效?

嘿,你搞定了吗?如果是的话,怎么做到的?我也在尝试做同样的事情,但不确定触发外部认证(例如谷歌)的 API 端点是什么。 - dragonfly02
我卡在这里了。@stt106,你解决了吗? - Kishan Vaishnav
我从未让这个工作起来。我们最终偶然走了另一条路。自从我发布这个问题以来已经有一段时间了,但如果可以避免的话,我不会使用资源所有者授权类型。我会设置一个完全独立的身份服务器并启用隐式流或授权代码流,并允许我的用户登录身份服务器。然后我会集成我需要的第三方提供商。我仍然不确定如何将第三方帐户连接到我的自定义用户,至少是最好的方式。 - Singularity222
@Singularity222 我找到了解决方案。 - Kishan Vaishnav
请遵循此答案 https://stackoverflow.com/a/62198723/9522887 - Kishan Vaishnav
1个回答

1

所有的功劳归功于Behrooz Dalvandi,感谢他发布了这篇this非常棒的文章。

解决此问题的方法是创建自定义授权并实现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”授权类型。
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"
                }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接