Skip to content

Commit d2540a0

Browse files
SuperOfficeDevNetAnthonyYates
authored andcommitted
Added support for SuperOffice dynamic userinfo subdomains (#756)
* Fixed tests, added support for dynamic userinfo subdomains * Update SuperOfficeAuthenticationHandler.cs --------- Co-authored-by: Tony Yates <[email protected]>
1 parent c5c968e commit d2540a0

File tree

5 files changed

+26
-14
lines changed

5 files changed

+26
-14
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ If a provider you're looking for does not exist, consider making a PR to add one
194194
| Stack Exchange | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.StackExchange?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.StackExchange/ "Download AspNet.Security.OAuth.StackExchange from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.StackExchange?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.StackExchange "Download AspNet.Security.OAuth.StackExchange from MyGet.org") | [Documentation](https://api.stackexchange.com/docs/authentication "Stack Exchange developer documentation") |
195195
| Strava | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Strava?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Strava/ "Download AspNet.Security.OAuth.Strava from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Strava?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Strava "Download AspNet.Security.OAuth.Strava from MyGet.org") | [Documentation](https://developers.strava.com/docs/authentication/ "Strava developer documentation") |
196196
| Streamlabs | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Streamlabs?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Streamlabs/ "Download AspNet.Security.OAuth.Streamlabs from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Streamlabs?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Streamlabs "Download AspNet.Security.OAuth.Streamlabs from MyGet.org") | [Documentation](https://dev.streamlabs.com/reference#authorize "Streamlabs developer documentation") |
197-
| SuperOffice | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.SuperOffice?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.SuperOffice/ "Download AspNet.Security.OAuth.SuperOffice from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.SuperOffice?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.SuperOffice "Download AspNet.Security.OAuth.SuperOffice from MyGet.org") | [Documentation](https://community.superoffice.com/en/developer/create-apps/concepts/authentication/ "SuperOffice developer documentation") |
197+
| SuperOffice | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.SuperOffice?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.SuperOffice/ "Download AspNet.Security.OAuth.SuperOffice from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.SuperOffice?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.SuperOffice "Download AspNet.Security.OAuth.SuperOffice from MyGet.org") | [Documentation](https://docs.superoffice.com/en/authentication/online/index.html "SuperOffice developer documentation") |
198198
| Trakt | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Trakt?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Trakt/ "Download AspNet.Security.OAuth.Trakt from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Trakt?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Trakt "Download AspNet.Security.OAuth.Trakt from MyGet.org") | [Documentation](https://trakt.docs.apiary.io/ "Trakt developer documentation") |
199199
| Trovo | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Trovo?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Trovo/ "Download AspNet.Security.OAuth.Trovo from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Trovo?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Trovo "Download AspNet.Security.OAuth.Trovo from MyGet.org") | [Documentation](https://developer.trovo.live/docs/APIs.html "Trovo developer documentation") |
200200
| Twitch | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Twitch?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Twitch/ "Download AspNet.Security.OAuth.Twitch from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Twitch?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Twitch "Download AspNet.Security.OAuth.Twitch from MyGet.org") | [Documentation](https://dev.twitch.tv/docs/authentication/ "Twitch developer documentation") |

src/AspNet.Security.OAuth.SuperOffice/SuperOfficeAuthenticationConstants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ internal static class FormatStrings
131131
/// </summary>
132132
/// <remarks>The final user information URL contains the protocol, host and tenant.</remarks>
133133
/// <example>https://sod.superoffice.com/Cust12345/api/v1/user/currentPrincipal</example>
134-
public const string UserInfoEndpoint = "/{0}/api/v1/user/currentPrincipal";
134+
public const string UserInfoEndpoint = "{0}v1/user/currentPrincipal";
135135
}
136136

137137
public static class PrincipalNames

src/AspNet.Security.OAuth.SuperOffice/SuperOfficeAuthenticationHandler.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,22 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
3636
[NotNull] AuthenticationProperties properties,
3737
[NotNull] OAuthTokenResponse tokens)
3838
{
39-
var contextId = await ProcessIdTokenAndGetContactIdentifierAsync(tokens, properties, identity);
39+
(string tenantId, string webApiUrl) = await ProcessIdTokenAndGetContactIdentifierAsync(tokens, properties, identity);
4040

41-
if (string.IsNullOrEmpty(contextId))
41+
if (string.IsNullOrEmpty(tenantId))
4242
{
4343
throw new InvalidOperationException("An error occurred trying to obtain the context identifier from the current user's identity claims.");
4444
}
4545

46-
// Add contextId to the Options.UserInformationEndpoint (https://sod.superoffice.com/{0}/api/v1/user/currentPrincipal).
47-
var userInfoEndpoint = string.Format(CultureInfo.InvariantCulture, Options.UserInformationEndpoint, contextId);
46+
if (string.IsNullOrEmpty(webApiUrl))
47+
{
48+
throw new InvalidOperationException("An error occurred trying to obtain the WebApi URL from the current user's identity claims.");
49+
}
50+
51+
// UserInfo endpoint must support multiple subdomains, i.e. sod, sod1, online, online1, online2, ...
52+
// - subdomain only becomes known from id token
53+
// Example WebApi Url https://sod.superoffice.com/Cust12345/api/
54+
var userInfoEndpoint = string.Format(CultureInfo.InvariantCulture, SuperOfficeAuthenticationConstants.FormatStrings.UserInfoEndpoint, webApiUrl);
4855

4956
// Get the SuperOffice user principal.
5057
using var request = new HttpRequestMessage(HttpMethod.Get, userInfoEndpoint);
@@ -69,7 +76,7 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
6976
return new AuthenticationTicket(context.Principal!, context.Properties, Scheme.Name);
7077
}
7178

72-
private async Task<string> ProcessIdTokenAndGetContactIdentifierAsync(
79+
private async Task<(string TenantId, string WebApiUrl)> ProcessIdTokenAndGetContactIdentifierAsync(
7380
[NotNull] OAuthTokenResponse tokens,
7481
[NotNull] AuthenticationProperties properties,
7582
[NotNull] ClaimsIdentity identity)
@@ -85,6 +92,7 @@ private async Task<string> ProcessIdTokenAndGetContactIdentifierAsync(
8592
var tokenValidationResult = await ValidateAsync(idToken, Options.TokenValidationParameters.Clone());
8693

8794
var contextIdentifier = string.Empty;
95+
var webApiUrl = string.Empty;
8896

8997
foreach (var claim in tokenValidationResult.ClaimsIdentity.Claims)
9098
{
@@ -93,6 +101,11 @@ private async Task<string> ProcessIdTokenAndGetContactIdentifierAsync(
93101
contextIdentifier = claim.Value;
94102
}
95103

104+
if (claim.Type == SuperOfficeAuthenticationConstants.ClaimNames.WebApiUrl)
105+
{
106+
webApiUrl = claim.Value;
107+
}
108+
96109
if (claim.Type == SuperOfficeAuthenticationConstants.ClaimNames.SubjectIdentifier)
97110
{
98111
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, claim.Value));
@@ -109,7 +122,7 @@ private async Task<string> ProcessIdTokenAndGetContactIdentifierAsync(
109122
}
110123
}
111124

112-
return contextIdentifier;
125+
return (contextIdentifier, webApiUrl);
113126
}
114127

115128
/// <summary>

src/AspNet.Security.OAuth.SuperOffice/SuperOfficeAuthenticationOptions.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@ private void UpdateEndpoints()
160160
FormatStrings.ClaimsIssuer,
161161
env);
162162

163-
// UserInformationEndpoint will include context identifier after authentication in SuperOfficeAuthenticationHandler.CreateTicketAsync
164-
UserInformationEndpoint = string.Concat(ClaimsIssuer, FormatStrings.UserInfoEndpoint);
165-
166163
MetadataAddress = string.Format(CultureInfo.InvariantCulture,
167164
FormatStrings.MetadataEndpoint,
168165
env);

test/AspNet.Security.OAuth.Providers.Tests/SuperOffice/bundle.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"contentJson": {
1010
"access_token": "8A:Cust12345.secret-access-token",
1111
"expires_in": "300",
12-
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2htLmRlbW8uc21pdGhAc3VwZXJvZmZpY2UuY29tIiwibmFtZSI6IkpvaG4gU21pdGgiLCJpc3MiOiJodHRwczovL3NvZC5zdXBlcm9mZmljZS5jb20iLCJpYXQiOjE5MjQzOTA4MDAsImV4cCI6MTkyNDM5MDgwMCwiYXVkIjoiZ2c0NTQ5MThkNzViMWI1MzEwMTA2NWMxNmVlNTExMjMiLCJodHRwOi8vc2NoZW1lcy5zdXBlcm9mZmljZS5uZXQvaWRlbnRpdHkvY3R4IjoiQ3VzdDEyMzQ1In0.XhHllwP6aRR4ZfXj1GlBxCEKKBldYkXef70eX4cjrvlYNLopk62nPnGl6-MxLqjrGHyDIHUo79K3p4_TbDnik2S6FYTeQS_BGNfXC9IuLxuuXnSjU-qhuHpUp1bMt9SBZkz91xDERkqEaTE3E6Q7WLmKAvKapXyJRas3DgAWUfc",
12+
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2htLmRlbW8uc21pdGhAc3VwZXJvZmZpY2UuY29tIiwibmFtZSI6IkpvaG4gU21pdGgiLCJpc3MiOiJodHRwczovL3NvZC5zdXBlcm9mZmljZS5jb20iLCJpYXQiOiIxOTI0MzkwODAwIiwiZXhwIjoxODMxODMyNDEwLCJhdWQiOlsiZ2c0NTQ5MThkNzViMWI1MzEwMTA2NWMxNmVlNTExMjMiLCJnZzQ1NDkxOGQ3NWIxYjUzMTAxMDY1YzE2ZWU1MTEyMyJdLCJodHRwOi8vc2NoZW1lcy5zdXBlcm9mZmljZS5uZXQvaWRlbnRpdHkvY3R4IjoiQ3VzdDEyMzQ1IiwiaHR0cDovL3NjaGVtZXMuc3VwZXJvZmZpY2UubmV0L2lkZW50aXR5L3RpY2tldCI6IjdUOlpRQTVBRElBTkFBM0FETUFNUUJoQURFQVpBQmpBRFlBTXdBM0FEVUFZUUF6QURjQU9RQmpBRGdBTmdBNUFEUUFOUUF6QURVQU9RQTRBR0VBWmdBekFEc0FPUUF5QURFQU5BQXhBRFVBTWdBM0FEVUFPd0JEQUhVQWN3QjBBRElBTmdBM0FEVUFPUUE9IiwiaHR0cDovL3NjaGVtZXMuc3VwZXJvZmZpY2UubmV0L2lkZW50aXR5L3NlcmlhbCI6IjEyMzQ1Njc4OSIsImh0dHA6Ly9zY2hlbWVzLnN1cGVyb2ZmaWNlLm5ldC9pZGVudGl0eS93ZWJhcGlfdXJsIjoiaHR0cHM6Ly9zb2Quc3VwZXJvZmZpY2UuY29tL0N1c3QxMjM0NS9hcGkvIiwibmJmIjoxNjc0MDY2MDEwfQ.kbqiDpeOmP0BzoeAxygefMlvkc_ZjoOkPW5luSdR7qKVRviypikg8joZhGpcgKFnx5lpN2hcAX8LR1Jm-g8IBHHNZtj1LU56OwQiDbradMjn_T4Ysqkyus50VBusVUnuOJUNoVZdUj-fwj8SdtLCPfFLGRS2y0EnOZFwvouB0szqybHM_XevSJe54JjSECHOlICXLvaZROvs8n4ZfoCKOIVMIObJ_wlEOHOJu3rnEk2t0srlE5uGbn-Xl-adNlOUM49Mffh6kcAGvjIxCNi2Pzx3_8k3UzdSwTDxef8E2nb20bbh_5qLch_m6rw_EYrJWEuJSQ_dOmd1MqBWoq-VDA",
1313
"refresh_token": "secret-refresh-token",
1414
"token_type": "bearer"
1515
}
@@ -88,10 +88,12 @@
8888
"kty": "RSA",
8989
"use": "sig",
9090
"alg": "RS256",
91-
"n": "o91XgZtL5WFwiz3jJAEhn2qWsMXRD1f9QJESXro2JIGeAr6jWRvFO8PC0J78PMe46abHDtYKSo49rJZNumADsrYEzUF_FWmvcB9yhEEAQoG9478SYatzzhgUUEebZ4ob5jJpAxNMCzbDJ_8w5rMXJJqy0lI4vUl6rj9akr29nrM",
91+
"kid": "B0AD4C0BFD8913B8040F3E8AD16A91F585222C33",
92+
"x5t": "sK1MC_2JE7gEDz6K0WqR9YUiLDM",
93+
"n": "we8Rh2LfdASEFRgE4VoLZomLl_9ZMowkXn7cjL23s2HYB5pG-ZldhSDyNXzGjNt6xpczhtfNy6Qo7nrleJM40_iXmcqUbIWHGqEPycixYyJVVgEcWXUujX12Xcnm8ZbgDlONXKday3rpAZBO909QzsxQtkcraToriQnOHgTPnbGMJC6kOIC_9qZv5u5wasMd97W21hhzQNVIpO5MlFT7YascGXJa95gjJ2kc975S1soTSOJrhkTe-osBO3fubSXlbyQfkF8HLqbBY2ds3HnV24QAusb7jVeQhiowSReiOoEcG-m6kFZQu3Tc3__1mWe1zeaGfDmuTNQsa2YZHeRLlQ",
9294
"e": "AQAB",
9395
"x5c": [
94-
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCj3VeBm0vlYXCLPeMkASGfapawxdEPV/1AkRJeujYkgZ4CvqNZG8U7w8LQnvw8x7jppscO1gpKjj2slk26YAOytgTNQX8Vaa9wH3KEQQBCgb3jvxJhq3POGBRQR5tnihvmMmkDE0wLNsMn/zDmsxckmrLSUji9SXquP1qSvb2eswIDAQAB"
96+
"MIIDyTCCArECFA/Y63b+pAFzyYckrH2eTPywxz2QMA0GCSqGSIb3DQEBCwUAMIGgMQswCQYDVQQGEwJOTzERMA8GA1UECAwIQWtlcmh1cnMxDTALBgNVBAcMBE9zbG8xGzAZBgNVBAoMElN1cGVyT2ZmaWNlIERldk5ldDEhMB8GA1UECwwYUmVzZWFyY2ggYW5kIERldmVsb3BtZW50MQswCQYDVQQDDAJEWDEiMCAGCSqGSIb3DQEJARYTc2RrQHN1cGVyb2ZmaWNlLmNvbTAeFw0yMTEyMTMyMDMzMDJaFw0yMjEyMTMyMDMzMDJaMIGgMQswCQYDVQQGEwJOTzERMA8GA1UECAwIQWtlcmh1cnMxDTALBgNVBAcMBE9zbG8xGzAZBgNVBAoMElN1cGVyT2ZmaWNlIERldk5ldDEhMB8GA1UECwwYUmVzZWFyY2ggYW5kIERldmVsb3BtZW50MQswCQYDVQQDDAJEWDEiMCAGCSqGSIb3DQEJARYTc2RrQHN1cGVyb2ZmaWNlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMHvEYdi33QEhBUYBOFaC2aJi5f/WTKMJF5+3Iy9t7Nh2AeaRvmZXYUg8jV8xozbesaXM4bXzcukKO565XiTONP4l5nKlGyFhxqhD8nIsWMiVVYBHFl1Lo19dl3J5vGW4A5TjVynWst66QGQTvdPUM7MULZHK2k6K4kJzh4Ez52xjCQupDiAv/amb+bucGrDHfe1ttYYc0DVSKTuTJRU+2GrHBlyWveYIydpHPe+UtbKE0jia4ZE3vqLATt37m0l5W8kH5BfBy6mwWNnbNx51duEALrG+41XkIYqMEkXojqBHBvpupBWULt03N//9Zlntc3mhnw5rkzULGtmGR3kS5UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAjBIAR7cG6r4gReI7S2Qs2zuD4Ghs6wTkPg0BHxoMnHYNN8E1Qig3KzE7BsZzO4gSA6w4kGx1nMSnAEStZMJSalU6LpUdf3xsl9XvM3EyNumk6r07mcphknNo0NFKc5DslITBImEteVcCK1qjWKZDrvH4Qf6VCItbn9v/jDkdzMsCBwA95FLvt0PI3J86rrHAYI9aqMb0q6qx5NbvPlsCTdVSJfqYYjY2acfTGkc3Bi9/phw8xR02gcU080SapftV+T/O0dd0bWL9XnLtHoioRMqIKbl4MRgDDszxV8jfAD3APbQCkHtiFcIU6PlLzU+Lc41Lxktre7JBKY3W3aHd0Q=="
9597
]
9698
}
9799
]

0 commit comments

Comments
 (0)