diff --git a/eng/PatchConfig.props b/eng/PatchConfig.props
index 5ce6494e432d..0a6db36788a2 100644
--- a/eng/PatchConfig.props
+++ b/eng/PatchConfig.props
@@ -15,6 +15,7 @@ Later on, this will be checked using this condition:
+ Microsoft.AspNetCore.Authentication.Google;
diff --git a/src/Security/Authentication/Google/src/GoogleDefaults.cs b/src/Security/Authentication/Google/src/GoogleDefaults.cs
index 04287031809f..2e6cf76e270d 100644
--- a/src/Security/Authentication/Google/src/GoogleDefaults.cs
+++ b/src/Security/Authentication/Google/src/GoogleDefaults.cs
@@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
+
namespace Microsoft.AspNetCore.Authentication.Google
{
///
@@ -16,6 +18,22 @@ public static class GoogleDefaults
public static readonly string TokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
- public static readonly string UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
+ public static readonly string UserInformationEndpoint;
+
+ private const string UseGooglePlusSwitch = "Switch.Microsoft.AspNetCore.Authentication.Google.UsePlus";
+
+ internal static readonly bool UseGooglePlus;
+
+ static GoogleDefaults()
+ {
+ if (AppContext.TryGetSwitch(UseGooglePlusSwitch, out UseGooglePlus) && UseGooglePlus)
+ {
+ UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
+ }
+ else
+ {
+ UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo";
+ }
+ }
}
}
diff --git a/src/Security/Authentication/Google/src/GoogleOptions.cs b/src/Security/Authentication/Google/src/GoogleOptions.cs
index 34028bc52b56..03abaeaada79 100644
--- a/src/Security/Authentication/Google/src/GoogleOptions.cs
+++ b/src/Security/Authentication/Google/src/GoogleOptions.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Security.Claims;
-using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Http;
@@ -27,11 +26,22 @@ public GoogleOptions()
Scope.Add("email");
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
- ClaimActions.MapJsonKey(ClaimTypes.Name, "displayName");
- ClaimActions.MapJsonSubKey(ClaimTypes.GivenName, "name", "givenName");
- ClaimActions.MapJsonSubKey(ClaimTypes.Surname, "name", "familyName");
- ClaimActions.MapJsonKey("urn:google:profile", "url");
- ClaimActions.MapCustomJson(ClaimTypes.Email, GoogleHelper.GetEmail);
+ if (GoogleDefaults.UseGooglePlus)
+ {
+ ClaimActions.MapJsonKey(ClaimTypes.Name, "displayName");
+ ClaimActions.MapJsonSubKey(ClaimTypes.GivenName, "name", "givenName");
+ ClaimActions.MapJsonSubKey(ClaimTypes.Surname, "name", "familyName");
+ ClaimActions.MapJsonKey("urn:google:profile", "url");
+ ClaimActions.MapCustomJson(ClaimTypes.Email, GoogleHelper.GetEmail);
+ }
+ else
+ {
+ ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
+ ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
+ ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
+ ClaimActions.MapJsonKey("urn:google:profile", "link");
+ ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
+ }
}
///
@@ -39,4 +49,4 @@ public GoogleOptions()
///
public string AccessType { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Security/Authentication/test/GoogleTests.cs b/src/Security/Authentication/test/GoogleTests.cs
index 511a658ff4ae..cba74a4bd944 100644
--- a/src/Security/Authentication/test/GoogleTests.cs
+++ b/src/Security/Authentication/test/GoogleTests.cs
@@ -809,45 +809,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string cla
{
o.ClaimsIssuer = claimsIssuer;
}
- o.BackchannelHttpHandler = new TestHttpMessageHandler
- {
- Sender = req =>
- {
- if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
- {
- return ReturnJsonResponse(new
- {
- access_token = "Test Access Token",
- expires_in = 3600,
- token_type = "Bearer"
- });
- }
- else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
- {
- return ReturnJsonResponse(new
- {
- id = "Test User ID",
- displayName = "Test Name",
- name = new
- {
- familyName = "Test Family Name",
- givenName = "Test Given Name"
- },
- url = "Profile link",
- emails = new[]
- {
- new
- {
- value = "Test email",
- type = "account"
- }
- }
- });
- }
-
- throw new NotImplementedException(req.RequestUri.AbsoluteUri);
- }
- };
+ o.BackchannelHttpHandler = CreateBackchannel();
});
var properties = new AuthenticationProperties();
@@ -999,46 +961,7 @@ public async Task AuthenticatedEventCanGetRefreshToken()
o.ClientId = "Test Id";
o.ClientSecret = "Test Secret";
o.StateDataFormat = stateFormat;
- o.BackchannelHttpHandler = new TestHttpMessageHandler
- {
- Sender = req =>
- {
- if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
- {
- return ReturnJsonResponse(new
- {
- access_token = "Test Access Token",
- expires_in = 3600,
- token_type = "Bearer",
- refresh_token = "Test Refresh Token"
- });
- }
- else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
- {
- return ReturnJsonResponse(new
- {
- id = "Test User ID",
- displayName = "Test Name",
- name = new
- {
- familyName = "Test Family Name",
- givenName = "Test Given Name"
- },
- url = "Profile link",
- emails = new[]
- {
- new
- {
- value = "Test email",
- type = "account"
- }
- }
- });
- }
-
- throw new NotImplementedException(req.RequestUri.AbsoluteUri);
- }
- };
+ o.BackchannelHttpHandler = CreateBackchannel();
o.Events = new OAuthEvents
{
OnCreatingTicket = context =>
@@ -1079,46 +1002,7 @@ public async Task NullRedirectUriWillRedirectToSlash()
o.ClientId = "Test Id";
o.ClientSecret = "Test Secret";
o.StateDataFormat = stateFormat;
- o.BackchannelHttpHandler = new TestHttpMessageHandler
- {
- Sender = req =>
- {
- if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
- {
- return ReturnJsonResponse(new
- {
- access_token = "Test Access Token",
- expires_in = 3600,
- token_type = "Bearer",
- refresh_token = "Test Refresh Token"
- });
- }
- else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
- {
- return ReturnJsonResponse(new
- {
- id = "Test User ID",
- displayName = "Test Name",
- name = new
- {
- familyName = "Test Family Name",
- givenName = "Test Given Name"
- },
- url = "Profile link",
- emails = new[]
- {
- new
- {
- value = "Test email",
- type = "account"
- }
- }
- });
- }
-
- throw new NotImplementedException(req.RequestUri.AbsoluteUri);
- }
- };
+ o.BackchannelHttpHandler = CreateBackchannel();
o.Events = new OAuthEvents
{
OnTicketReceived = context =>
@@ -1169,46 +1053,7 @@ public async Task ValidateAuthenticatedContext()
return Task.FromResult(0);
}
};
- o.BackchannelHttpHandler = new TestHttpMessageHandler
- {
- Sender = req =>
- {
- if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
- {
- return ReturnJsonResponse(new
- {
- access_token = "Test Access Token",
- expires_in = 3600,
- token_type = "Bearer",
- refresh_token = "Test Refresh Token"
- });
- }
- else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
- {
- return ReturnJsonResponse(new
- {
- id = "Test User ID",
- displayName = "Test Name",
- name = new
- {
- familyName = "Test Family Name",
- givenName = "Test Given Name"
- },
- url = "Profile link",
- emails = new[]
- {
- new
- {
- value = "Test email",
- type = "account"
- }
- }
- });
- }
-
- throw new NotImplementedException(req.RequestUri.AbsoluteUri);
- }
- };
+ o.BackchannelHttpHandler = CreateBackchannel();
});
var properties = new AuthenticationProperties();
@@ -1439,29 +1284,20 @@ private HttpMessageHandler CreateBackchannel()
{
access_token = "Test Access Token",
expires_in = 3600,
- token_type = "Bearer"
+ token_type = "Bearer",
+ refresh_token = "Test Refresh Token"
});
}
- else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
+ else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/oauth2/v2/userinfo")
{
return ReturnJsonResponse(new
{
id = "Test User ID",
- displayName = "Test Name",
- name = new
- {
- familyName = "Test Family Name",
- givenName = "Test Given Name"
- },
- url = "Profile link",
- emails = new[]
- {
- new
- {
- value = "Test email",
- type = "account"
- }
- }
+ name = "Test Name",
+ given_name = "Test Given Name",
+ family_name = "Test Family Name",
+ link = "Profile link",
+ email = "Test email",
});
}
diff --git a/src/Security/Security.sln b/src/Security/Security.sln
index b8aa6968a45d..3d36597db9d3 100644
--- a/src/Security/Security.sln
+++ b/src/Security/Security.sln
@@ -96,12 +96,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagno
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.StaticFiles", "..\Middleware\StaticFiles\src\Microsoft.AspNetCore.StaticFiles.csproj", "{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{43AF597A-FCB8-41A5-8279-345FEE9A61AD}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel", "..\Servers\Kestrel\Kestrel\src\Microsoft.AspNetCore.Server.Kestrel.csproj", "{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel.Https", "..\Servers\Kestrel\Https\src\Microsoft.AspNetCore.Server.Kestrel.Https.csproj", "{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -236,10 +236,6 @@ Global
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Release|Any CPU.Build.0 = Release|Any CPU
- {43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Release|Any CPU.Build.0 = Release|Any CPU
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -248,6 +244,10 @@ Global
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -295,9 +295,9 @@ Global
{B6CA96E4-674A-4616-9A38-DED07BE458E1} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
{54CBBAED-36D5-4855-BB4E-D1AE3523AA23} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
- {43AF597A-FCB8-41A5-8279-345FEE9A61AD} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
+ {81D0E81F-4711-4C7B-BBD4-E168102D0D7D} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {ABF8089E-43D0-4010-84A7-7A9DCFE49357}