Aspnet Core 1.1 migrate to new Google Sign-In

217 Views Asked by At

I've built an AspnetCore 1.1 Web Application and I've to migrate authentication from Google + Sign In to new Google Sign In. I've found on web many suggestions for AspNet Core 2.x but noone for AspNet Core 1.x. One of these suggestions was to add following code to startup class:

services.AddAuthentication().AddGoogle(googleOptions =>  
{  
    googleOptions.ClientId = Configuration["Authentication:Google:ClientId"];  
    googleOptions.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
    googleOptions.UserInformationEndpoint = "https://openidconnect.googleapis.com/v1/userinfo";
    googleOptions.ClaimActions.Clear();
    googleOptions.ClaimActions.MapJsonKey(ClaimTypes.Name, "email");
    googleOptions.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_Name");
    googleOptions.ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_Name");
    googleOptions.ClaimActions.MapJsonKey("urn:google:profile", "profile");
    googleOptions.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
    googleOptions.ClaimActions.MapJsonKey("urn:google:image", "picture");
    googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
});

My problem, in this case, is that with AspNet Core 1.x I've not "ClaimActions.MapJsonKey()" method and I don't know how to translate this code for Core 1.x.

Can someone help me? Is there another solution for AspNet Core 1.x?

Thanks in advance

1

There are 1 best solutions below

2
Tseng On BEST ANSWER

On breaking changes always check ASP.NET Core Announcements GitHub repository.

Microsoft.Owin with ASP.NET Web Forms and MVC For Microsoft.Owin 3.1.0 and later a temporary mitigation is outlined here. Applications should do immediate testing with the mitigation to check for changes in the data format. We'll plan to release Microsoft.Owin 4.0.1 with a fix for this as soon as possible. Applications using any prior version will need to update to 4.0.1.

ASP.NET Core 1.x The mitigation given above for Microsoft.Owin can also be adapted for ASP.NET Core 1.x. As 1.x is nearing end of life and has low usage there are no plans to patch the NuGet packages for this issue.

The links in the issue show on this comment.

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
    ClientId = Environment.GetEnvironmentVariable("google:clientid"),
    ClientSecret = Environment.GetEnvironmentVariable("google:clientsecret"),
    UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo",
    BackchannelHttpHandler = new GoogleUserInfoRemapper(new WebRequestHandler())
});

and

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace Katana.Sandbox.WebServer
{
    internal class GoogleUserInfoRemapper : DelegatingHandler
    {
        public GoogleUserInfoRemapper(HttpMessageHandler innerHandler) : base(innerHandler) { }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);

            if (!request.RequestUri.AbsoluteUri.Equals("https://www.googleapis.com/oauth2/v2/userinfo"))
            {
                return response;
            }

            response.EnsureSuccessStatusCode();
            var text = await response.Content.ReadAsStringAsync();
            JObject user = JObject.Parse(text);
            JObject legacyFormat = new JObject();

            JToken token;
            if (user.TryGetValue("id", out token))
            {
                legacyFormat["id"] = token;
            }
            if (user.TryGetValue("name", out token))
            {
                legacyFormat["displayName"] = token;
            }
            JToken given, family;
            if (user.TryGetValue("given_name", out given) && user.TryGetValue("family_name", out family))
            {
                var name = new JObject();
                name["givenName"] = given;
                name["familyName"] = family;
                legacyFormat["name"] = name;
            }
            if (user.TryGetValue("link", out token))
            {
                legacyFormat["url"] = token;
            }
            if (user.TryGetValue("email", out token))
            {
                var email = new JObject();
                email["value"] = token;
                legacyFormat["emails"] = new JArray(email);
            }
            if (user.TryGetValue("picture", out token))
            {
                var image = new JObject();
                image["url"] = token;
                legacyFormat["image"] = image;
            }

            text = legacyFormat.ToString();
            response.Content = new StringContent(text);
            return response;
        }
    }
}