Skip to content

Commit f5e886f

Browse files
committed
Update Google Auth UserInfo endpoint #6069
1 parent 8aa8c6b commit f5e886f

File tree

4 files changed

+55
-191
lines changed

4 files changed

+55
-191
lines changed

src/Security/Authentication/Google/src/GoogleDefaults.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
5+
46
namespace Microsoft.AspNetCore.Authentication.Google
57
{
68
/// <summary>
@@ -16,6 +18,22 @@ public static class GoogleDefaults
1618

1719
public static readonly string TokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
1820

19-
public static readonly string UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
21+
public static readonly string UserInformationEndpoint;
22+
23+
private const string UseGooglePlusSwitch = "Switch.Microsoft.AspNetCore.Authentication.Google.UsePlus";
24+
25+
internal static readonly bool UseGooglePlus;
26+
27+
static GoogleDefaults()
28+
{
29+
if (AppContext.TryGetSwitch(UseGooglePlusSwitch, out UseGooglePlus) && UseGooglePlus)
30+
{
31+
UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
32+
}
33+
else
34+
{
35+
UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo";
36+
}
37+
}
2038
}
2139
}

src/Security/Authentication/Google/src/GoogleOptions.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System.Security.Claims;
5-
using Microsoft.AspNetCore.Authentication;
65
using Microsoft.AspNetCore.Authentication.OAuth;
76
using Microsoft.AspNetCore.Http;
87

@@ -27,16 +26,27 @@ public GoogleOptions()
2726
Scope.Add("email");
2827

2928
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
30-
ClaimActions.MapJsonKey(ClaimTypes.Name, "displayName");
31-
ClaimActions.MapJsonSubKey(ClaimTypes.GivenName, "name", "givenName");
32-
ClaimActions.MapJsonSubKey(ClaimTypes.Surname, "name", "familyName");
33-
ClaimActions.MapJsonKey("urn:google:profile", "url");
34-
ClaimActions.MapCustomJson(ClaimTypes.Email, GoogleHelper.GetEmail);
29+
if (GoogleDefaults.UseGooglePlus)
30+
{
31+
ClaimActions.MapJsonKey(ClaimTypes.Name, "displayName");
32+
ClaimActions.MapJsonSubKey(ClaimTypes.GivenName, "name", "givenName");
33+
ClaimActions.MapJsonSubKey(ClaimTypes.Surname, "name", "familyName");
34+
ClaimActions.MapJsonKey("urn:google:profile", "url");
35+
ClaimActions.MapCustomJson(ClaimTypes.Email, GoogleHelper.GetEmail);
36+
}
37+
else
38+
{
39+
ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
40+
ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
41+
ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
42+
ClaimActions.MapJsonKey("urn:google:profile", "link");
43+
ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
44+
}
3545
}
3646

3747
/// <summary>
3848
/// access_type. Set to 'offline' to request a refresh token.
3949
/// </summary>
4050
public string AccessType { get; set; }
4151
}
42-
}
52+
}

src/Security/Authentication/test/GoogleTests.cs

Lines changed: 12 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -809,45 +809,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string cla
809809
{
810810
o.ClaimsIssuer = claimsIssuer;
811811
}
812-
o.BackchannelHttpHandler = new TestHttpMessageHandler
813-
{
814-
Sender = req =>
815-
{
816-
if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
817-
{
818-
return ReturnJsonResponse(new
819-
{
820-
access_token = "Test Access Token",
821-
expires_in = 3600,
822-
token_type = "Bearer"
823-
});
824-
}
825-
else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
826-
{
827-
return ReturnJsonResponse(new
828-
{
829-
id = "Test User ID",
830-
displayName = "Test Name",
831-
name = new
832-
{
833-
familyName = "Test Family Name",
834-
givenName = "Test Given Name"
835-
},
836-
url = "Profile link",
837-
emails = new[]
838-
{
839-
new
840-
{
841-
value = "Test email",
842-
type = "account"
843-
}
844-
}
845-
});
846-
}
847-
848-
throw new NotImplementedException(req.RequestUri.AbsoluteUri);
849-
}
850-
};
812+
o.BackchannelHttpHandler = CreateBackchannel();
851813
});
852814

853815
var properties = new AuthenticationProperties();
@@ -999,46 +961,7 @@ public async Task AuthenticatedEventCanGetRefreshToken()
999961
o.ClientId = "Test Id";
1000962
o.ClientSecret = "Test Secret";
1001963
o.StateDataFormat = stateFormat;
1002-
o.BackchannelHttpHandler = new TestHttpMessageHandler
1003-
{
1004-
Sender = req =>
1005-
{
1006-
if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
1007-
{
1008-
return ReturnJsonResponse(new
1009-
{
1010-
access_token = "Test Access Token",
1011-
expires_in = 3600,
1012-
token_type = "Bearer",
1013-
refresh_token = "Test Refresh Token"
1014-
});
1015-
}
1016-
else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
1017-
{
1018-
return ReturnJsonResponse(new
1019-
{
1020-
id = "Test User ID",
1021-
displayName = "Test Name",
1022-
name = new
1023-
{
1024-
familyName = "Test Family Name",
1025-
givenName = "Test Given Name"
1026-
},
1027-
url = "Profile link",
1028-
emails = new[]
1029-
{
1030-
new
1031-
{
1032-
value = "Test email",
1033-
type = "account"
1034-
}
1035-
}
1036-
});
1037-
}
1038-
1039-
throw new NotImplementedException(req.RequestUri.AbsoluteUri);
1040-
}
1041-
};
964+
o.BackchannelHttpHandler = CreateBackchannel();
1042965
o.Events = new OAuthEvents
1043966
{
1044967
OnCreatingTicket = context =>
@@ -1079,46 +1002,7 @@ public async Task NullRedirectUriWillRedirectToSlash()
10791002
o.ClientId = "Test Id";
10801003
o.ClientSecret = "Test Secret";
10811004
o.StateDataFormat = stateFormat;
1082-
o.BackchannelHttpHandler = new TestHttpMessageHandler
1083-
{
1084-
Sender = req =>
1085-
{
1086-
if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
1087-
{
1088-
return ReturnJsonResponse(new
1089-
{
1090-
access_token = "Test Access Token",
1091-
expires_in = 3600,
1092-
token_type = "Bearer",
1093-
refresh_token = "Test Refresh Token"
1094-
});
1095-
}
1096-
else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
1097-
{
1098-
return ReturnJsonResponse(new
1099-
{
1100-
id = "Test User ID",
1101-
displayName = "Test Name",
1102-
name = new
1103-
{
1104-
familyName = "Test Family Name",
1105-
givenName = "Test Given Name"
1106-
},
1107-
url = "Profile link",
1108-
emails = new[]
1109-
{
1110-
new
1111-
{
1112-
value = "Test email",
1113-
type = "account"
1114-
}
1115-
}
1116-
});
1117-
}
1118-
1119-
throw new NotImplementedException(req.RequestUri.AbsoluteUri);
1120-
}
1121-
};
1005+
o.BackchannelHttpHandler = CreateBackchannel();
11221006
o.Events = new OAuthEvents
11231007
{
11241008
OnTicketReceived = context =>
@@ -1169,46 +1053,7 @@ public async Task ValidateAuthenticatedContext()
11691053
return Task.FromResult(0);
11701054
}
11711055
};
1172-
o.BackchannelHttpHandler = new TestHttpMessageHandler
1173-
{
1174-
Sender = req =>
1175-
{
1176-
if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
1177-
{
1178-
return ReturnJsonResponse(new
1179-
{
1180-
access_token = "Test Access Token",
1181-
expires_in = 3600,
1182-
token_type = "Bearer",
1183-
refresh_token = "Test Refresh Token"
1184-
});
1185-
}
1186-
else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
1187-
{
1188-
return ReturnJsonResponse(new
1189-
{
1190-
id = "Test User ID",
1191-
displayName = "Test Name",
1192-
name = new
1193-
{
1194-
familyName = "Test Family Name",
1195-
givenName = "Test Given Name"
1196-
},
1197-
url = "Profile link",
1198-
emails = new[]
1199-
{
1200-
new
1201-
{
1202-
value = "Test email",
1203-
type = "account"
1204-
}
1205-
}
1206-
});
1207-
}
1208-
1209-
throw new NotImplementedException(req.RequestUri.AbsoluteUri);
1210-
}
1211-
};
1056+
o.BackchannelHttpHandler = CreateBackchannel();
12121057
});
12131058

12141059
var properties = new AuthenticationProperties();
@@ -1439,29 +1284,20 @@ private HttpMessageHandler CreateBackchannel()
14391284
{
14401285
access_token = "Test Access Token",
14411286
expires_in = 3600,
1442-
token_type = "Bearer"
1287+
token_type = "Bearer",
1288+
refresh_token = "Test Refresh Token"
14431289
});
14441290
}
1445-
else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
1291+
else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/oauth2/v2/userinfo")
14461292
{
14471293
return ReturnJsonResponse(new
14481294
{
14491295
id = "Test User ID",
1450-
displayName = "Test Name",
1451-
name = new
1452-
{
1453-
familyName = "Test Family Name",
1454-
givenName = "Test Given Name"
1455-
},
1456-
url = "Profile link",
1457-
emails = new[]
1458-
{
1459-
new
1460-
{
1461-
value = "Test email",
1462-
type = "account"
1463-
}
1464-
}
1296+
name = "Test Name",
1297+
given_name = "Test Given Name",
1298+
family_name = "Test Family Name",
1299+
link = "Profile link",
1300+
email = "Test email",
14651301
});
14661302
}
14671303

src/Security/Security.sln

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagno
9696
EndProject
9797
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.StaticFiles", "..\Middleware\StaticFiles\src\Microsoft.AspNetCore.StaticFiles.csproj", "{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}"
9898
EndProject
99-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{43AF597A-FCB8-41A5-8279-345FEE9A61AD}"
100-
EndProject
10199
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel", "..\Servers\Kestrel\Kestrel\src\Microsoft.AspNetCore.Server.Kestrel.csproj", "{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}"
102100
EndProject
103101
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}"
104102
EndProject
103+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}"
104+
EndProject
105105
Global
106106
GlobalSection(SolutionConfigurationPlatforms) = preSolution
107107
Debug|Any CPU = Debug|Any CPU
@@ -236,10 +236,6 @@ Global
236236
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Debug|Any CPU.Build.0 = Debug|Any CPU
237237
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Release|Any CPU.ActiveCfg = Release|Any CPU
238238
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Release|Any CPU.Build.0 = Release|Any CPU
239-
{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
240-
{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
241-
{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
242-
{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Release|Any CPU.Build.0 = Release|Any CPU
243239
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
244240
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
245241
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -248,6 +244,10 @@ Global
248244
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
249245
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
250246
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Release|Any CPU.Build.0 = Release|Any CPU
247+
{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
248+
{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
249+
{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
250+
{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Release|Any CPU.Build.0 = Release|Any CPU
251251
EndGlobalSection
252252
GlobalSection(SolutionProperties) = preSolution
253253
HideSolutionNode = FALSE
@@ -295,9 +295,9 @@ Global
295295
{B6CA96E4-674A-4616-9A38-DED07BE458E1} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
296296
{54CBBAED-36D5-4855-BB4E-D1AE3523AA23} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
297297
{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
298-
{43AF597A-FCB8-41A5-8279-345FEE9A61AD} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
299298
{707CBFB4-4D35-479E-9BAF-39B4DA9782DE} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
300299
{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
300+
{81D0E81F-4711-4C7B-BBD4-E168102D0D7D} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
301301
EndGlobalSection
302302
GlobalSection(ExtensibilityGlobals) = postSolution
303303
SolutionGuid = {ABF8089E-43D0-4010-84A7-7A9DCFE49357}

0 commit comments

Comments
 (0)