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

时间:2017-11-14 17:20:39

标签: identityserver4 asp.net-core-identity

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

是否有办法让应用程序中的资源所有者密码授予类型可用于“本地”用户,还可以通过Google启用第三方身份验证?目前,我们使用用户名和密码访问Identity Server令牌端点,并将令牌存储在浏览器中。然后将其传递给任何需要授权的端点。在集成Google身份验证和检索Google令牌时,此相同的流程是否仍然有效?

1 个答案:

答案 0 :(得分: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"
                }
            }