Skip to content

Commit 504cc8a

Browse files
jerriepkevinchalet
authored andcommitted
Update the Slack provider to use a unique identifier for ClaimTypes.NameIdentifier
1 parent c8c923a commit 504cc8a

File tree

4 files changed

+31
-80
lines changed

4 files changed

+31
-80
lines changed

src/AspNet.Security.OAuth.Slack/SlackAuthenticationDefaults.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public static class SlackAuthenticationDefaults
4545

4646
/// <summary>
4747
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/>.
48-
/// For more info about this endpoint, see https://api.slack.com/methods/auth.test.
48+
/// For more info about this endpoint, see https://api.slack.com/methods/users.identity.
4949
/// </summary>
50-
public const string UserInformationEndpoint = "https://slack.com/api/auth.test";
50+
public const string UserInformationEndpoint = "https://slack.com/api/users.identity";
5151
}
5252
}

src/AspNet.Security.OAuth.Slack/SlackAuthenticationHandler.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,12 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync([NotNull]
4848

4949
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
5050

51-
identity.AddOptionalClaim(ClaimTypes.NameIdentifier, SlackAuthenticationHelper.GetUserIdentifier(payload), Options.ClaimsIssuer)
51+
identity.AddOptionalClaim(ClaimTypes.NameIdentifier, SlackAuthenticationHelper.GetUniqueIdentifier(payload), Options.ClaimsIssuer)
5252
.AddOptionalClaim(ClaimTypes.Name, SlackAuthenticationHelper.GetUserName(payload), Options.ClaimsIssuer)
53+
.AddOptionalClaim(ClaimTypes.Email, SlackAuthenticationHelper.GetUserEmail(payload), Options.ClaimsIssuer)
54+
.AddOptionalClaim("urn:slack:user_id", SlackAuthenticationHelper.GetUserIdentifier(payload), Options.ClaimsIssuer)
5355
.AddOptionalClaim("urn:slack:team_id", SlackAuthenticationHelper.GetTeamIdentifier(payload), Options.ClaimsIssuer)
54-
.AddOptionalClaim("urn:slack:team_name", SlackAuthenticationHelper.GetTeamName(payload), Options.ClaimsIssuer)
55-
.AddOptionalClaim("urn:slack:team_url", SlackAuthenticationHelper.GetTeamLink(payload), Options.ClaimsIssuer)
56-
.AddOptionalClaim("urn:slack:bot:user_id", SlackAuthenticationHelper.GetBotUserId(payload), Options.ClaimsIssuer)
57-
.AddOptionalClaim("urn:slack:bot:access_token", SlackAuthenticationHelper.GetBotAccessToken(payload), Options.ClaimsIssuer)
58-
.AddOptionalClaim("urn:slack:webhook:channel", SlackAuthenticationHelper.GetWebhookChannel(payload), Options.ClaimsIssuer)
59-
.AddOptionalClaim("urn:slack:webhook:url", SlackAuthenticationHelper.GetWebhookURL(payload), Options.ClaimsIssuer)
60-
.AddOptionalClaim("urn:slack:webhook:configuration_url", SlackAuthenticationHelper.GetWebhookConfigurationURL(payload), Options.ClaimsIssuer);
56+
.AddOptionalClaim("urn:slack:team_name", SlackAuthenticationHelper.GetTeamName(payload), Options.ClaimsIssuer);
6157

6258
var principal = new ClaimsPrincipal(identity);
6359
var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme);

src/AspNet.Security.OAuth.Slack/SlackAuthenticationHelper.cs

Lines changed: 23 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -17,133 +17,86 @@ namespace AspNet.Security.OAuth.Slack
1717
public static class SlackAuthenticationHelper
1818
{
1919
/// <summary>
20-
/// Gets the identifier corresponding to the authenticated user.
21-
/// </summary>
22-
public static string GetUserIdentifier([NotNull] JObject user)
23-
{
24-
if (user == null)
25-
{
26-
throw new ArgumentNullException(nameof(user));
27-
}
28-
29-
return user.Value<string>("user_id");
30-
}
31-
32-
/// <summary>
33-
/// Gets the login corresponding to the authenticated user.
34-
/// </summary>
35-
public static string GetUserName([NotNull] JObject user)
36-
{
37-
if (user == null)
38-
{
39-
throw new ArgumentNullException(nameof(user));
40-
}
41-
42-
return user.Value<string>("user");
43-
}
44-
45-
/// <summary>
46-
/// Gets the name corresponding to the authenticated user.
47-
/// </summary>
48-
public static string GetTeamIdentifier([NotNull] JObject user)
49-
{
50-
if (user == null)
51-
{
52-
throw new ArgumentNullException(nameof(user));
53-
}
54-
55-
return user.Value<string>("team_id");
56-
}
57-
58-
/// <summary>
59-
/// Gets the name corresponding to the authenticated user.
60-
/// </summary>
61-
public static string GetTeamName([NotNull] JObject user)
62-
{
63-
if (user == null)
64-
{
65-
throw new ArgumentNullException(nameof(user));
66-
}
67-
68-
return user.Value<string>("team");
69-
}
70-
71-
/// <summary>
72-
/// Gets the URL corresponding to the authenticated user.
20+
/// Gets a unique identifer for the authenticated user.
7321
/// </summary>
74-
public static string GetTeamLink([NotNull] JObject user)
22+
/// <remarks>
23+
/// Note: according to the Slack API documentation (https://api.slack.com/methods/users.identity),
24+
/// user identifiers are not guaranteed to be globally unique across teams. The combination of
25+
/// the user and team identifiers on the other hand, is guaranteed to be globally unique.
26+
/// </remarks>
27+
public static string GetUniqueIdentifier([NotNull] JObject user)
7528
{
7629
if (user == null)
7730
{
7831
throw new ArgumentNullException(nameof(user));
7932
}
8033

81-
return user.Value<string>("url");
34+
return string.Concat(GetTeamIdentifier(user), "|", GetUserIdentifier(user));
8235
}
8336

8437
/// <summary>
85-
/// Gets the identifier associated with the bot.
38+
/// Gets the email address corresponding to the authenticated user.
8639
/// </summary>
87-
public static string GetBotUserId([NotNull] JObject user)
40+
public static string GetUserEmail([NotNull] JObject user)
8841
{
8942
if (user == null)
9043
{
9144
throw new ArgumentNullException(nameof(user));
9245
}
9346

94-
return user["bot"]?.Value<string>("bot_user_id");
47+
return user.Value<JObject>("user")?.Value<string>("email");
9548
}
9649

9750
/// <summary>
98-
/// Gets the access token associated with the bot.
51+
/// Gets the identifier corresponding to the authenticated user.
9952
/// </summary>
100-
public static string GetBotAccessToken([NotNull] JObject user)
53+
public static string GetUserIdentifier([NotNull] JObject user)
10154
{
10255
if (user == null)
10356
{
10457
throw new ArgumentNullException(nameof(user));
10558
}
10659

107-
return user["bot"]?.Value<string>("bot_access_token");
60+
return user.Value<JObject>("user")?.Value<string>("id");
10861
}
10962

11063
/// <summary>
111-
/// Gets the channel name of the selected webhook.
64+
/// Gets the login corresponding to the authenticated user.
11265
/// </summary>
113-
public static string GetWebhookChannel([NotNull] JObject user)
66+
public static string GetUserName([NotNull] JObject user)
11467
{
11568
if (user == null)
11669
{
11770
throw new ArgumentNullException(nameof(user));
11871
}
11972

120-
return user["incoming_webhook"]?.Value<string>("channel");
73+
return user.Value<JObject>("user")?.Value<string>("name");
12174
}
12275

12376
/// <summary>
124-
/// Gets the URL of the selected webhook.
77+
/// Gets the name corresponding to the authenticated user.
12578
/// </summary>
126-
public static string GetWebhookURL([NotNull] JObject user)
79+
public static string GetTeamIdentifier([NotNull] JObject user)
12780
{
12881
if (user == null)
12982
{
13083
throw new ArgumentNullException(nameof(user));
13184
}
13285

133-
return user["incoming_webhook"]?.Value<string>("url");
86+
return user.Value<JObject>("team")?.Value<string>("id");
13487
}
13588

13689
/// <summary>
137-
/// Gets the channel configuration URL of the selected webhook.
90+
/// Gets the name corresponding to the authenticated user.
13891
/// </summary>
139-
public static string GetWebhookConfigurationURL([NotNull] JObject user)
92+
public static string GetTeamName([NotNull] JObject user)
14093
{
14194
if (user == null)
14295
{
14396
throw new ArgumentNullException(nameof(user));
14497
}
14598

146-
return user["incoming_webhook"]?.Value<string>("configuration_url");
99+
return user.Value<JObject>("team")?.Value<string>("name");
147100
}
148101
}
149102
}

src/AspNet.Security.OAuth.Slack/SlackAuthenticationOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public SlackAuthenticationOptions()
2525
AuthorizationEndpoint = SlackAuthenticationDefaults.AuthorizationEndpoint;
2626
TokenEndpoint = SlackAuthenticationDefaults.TokenEndpoint;
2727
UserInformationEndpoint = SlackAuthenticationDefaults.UserInformationEndpoint;
28+
29+
Scope.Add("identity.basic");
2830
}
2931
}
3032
}

0 commit comments

Comments
 (0)