Identity Server 4 - Resource Owner Password Grant and Google Authentication

不想你离开。 提交于 2020-06-27 12:59:12

问题


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.

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?


回答1:


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

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

Configure this validator in the Startup

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

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


来源:https://stackoverflow.com/questions/47291734/identity-server-4-resource-owner-password-grant-and-google-authentication

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!