Skip to content

Commit ba8c2a4

Browse files
committed
Aligned cache key generation.
Removed stored tokens and API keys from the cache when access is revoked.
1 parent ee4922c commit ba8c2a4

File tree

7 files changed

+72
-23
lines changed

7 files changed

+72
-23
lines changed

src/Umbraco.AuthorizedServices/Constants.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,6 @@ public static class Trees
4242
public const string AuthorizedServices = nameof(AuthorizedServices);
4343
}
4444

45-
public static class Cache
46-
{
47-
public const string AuthorizationPayloadKeyFormat = "Umbraco_AuthorizedServices_Payload_{0}";
48-
49-
public const string AuthorizationTokenFormat = "Umbraco_AuthorizedServices_Token_{0}";
50-
}
51-
5245
public static class OAuth1
5346
{
5447
public const string OAuthToken = "oauth_token";

src/Umbraco.AuthorizedServices/Controllers/AuthorizedServiceController.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System.IO;
21
using System.Net;
3-
using System.Security.AccessControl;
4-
using Azure;
52
using Microsoft.AspNetCore.Authorization;
63
using Microsoft.AspNetCore.Mvc;
74
using Microsoft.Extensions.Options;
@@ -79,7 +76,7 @@ public AuthorizedServiceController(
7976
{
8077
AuthorizationPayload authorizationPayload = _authorizationPayloadBuilder.BuildPayload();
8178

82-
var cacheKey = string.Format(Constants.Cache.AuthorizationPayloadKeyFormat, alias);
79+
var cacheKey = CacheHelper.GetPayloadKey(alias);
8380
_appCaches.RuntimeCache.Insert(cacheKey, () => authorizationPayload);
8481

8582
authorizationUrl = _authorizationUrlBuilder
@@ -167,13 +164,16 @@ public IActionResult RevokeAccess(RevokeAccess model)
167164
{
168165
case AuthenticationMethod.ApiKey:
169166
_keyStorage.DeleteKey(model.Alias);
167+
ClearCachedApiKey(model.Alias);
170168
break;
171169
case AuthenticationMethod.OAuth1:
172170
_oauth1TokenStorage.DeleteToken(model.Alias);
171+
ClearCachedToken(model.Alias);
173172
break;
174173
case AuthenticationMethod.OAuth2AuthorizationCode:
175174
case AuthenticationMethod.OAuth2ClientCredentials:
176175
_oauth2TokenStorage.DeleteToken(model.Alias);
176+
ClearCachedToken(model.Alias);
177177
break;
178178
default:
179179
throw new ArgumentOutOfRangeException(nameof(serviceDetail.AuthenticationMethod));
@@ -182,6 +182,18 @@ public IActionResult RevokeAccess(RevokeAccess model)
182182
return Ok();
183183
}
184184

185+
private void ClearCachedApiKey(string serviceAlias)
186+
{
187+
var cacheKey = CacheHelper.GetApiKeyCacheKey(serviceAlias);
188+
_appCaches.RuntimeCache.ClearByKey(cacheKey);
189+
}
190+
191+
private void ClearCachedToken(string serviceAlias)
192+
{
193+
var cacheKey = CacheHelper.GetTokenCacheKey(serviceAlias);
194+
_appCaches.RuntimeCache.ClearByKey(cacheKey);
195+
}
196+
185197
/// <summary>
186198
/// Adds a new access token for an OAuth2 authorized service.
187199
/// </summary>
@@ -252,7 +264,7 @@ public async Task<IActionResult> GenerateOAuth1RequestToken(GenerateToken model)
252264
{
253265
_appCaches.RuntimeCache.InsertCacheItem(oauthToken, () => serviceDetail.Alias);
254266

255-
_appCaches.RuntimeCache.InsertCacheItem($"{serviceDetail.Alias}-oauth-token-secret", () => oauthTokenSecret);
267+
_appCaches.RuntimeCache.InsertCacheItem(CacheHelper.GetTokenSecretCacheKey(serviceDetail.Alias), () => oauthTokenSecret);
256268

257269
return Ok(string.Format(
258270
"{0}{1}?{2}",

src/Umbraco.AuthorizedServices/Controllers/AuthorizedServiceResponseController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Umbraco.AuthorizedServices.Configuration;
44
using Umbraco.AuthorizedServices.Exceptions;
55
using Umbraco.AuthorizedServices.Extensions;
6+
using Umbraco.AuthorizedServices.Helpers;
67
using Umbraco.AuthorizedServices.Models;
78
using Umbraco.AuthorizedServices.Services;
89
using Umbraco.Cms.Core.Cache;
@@ -45,7 +46,7 @@ public async Task<IActionResult> HandleOAuth2IdentityResponse(string code, strin
4546
throw new AuthorizedServiceException("The state provided in the identity response could not be parsed.");
4647
}
4748

48-
var cacheKey = string.Format(Constants.Cache.AuthorizationPayloadKeyFormat, stateParts[0]);
49+
var cacheKey = CacheHelper.GetPayloadKey(stateParts[0]);
4950
if (_appCaches.RuntimeCache.Get(cacheKey) is not AuthorizationPayload cachedAuthorizationPayload || stateParts[1] != cachedAuthorizationPayload.State)
5051
{
5152
throw new AuthorizedServiceException("The state provided in the identity response did not match the expected value.");
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace Umbraco.AuthorizedServices.Helpers
2+
{
3+
internal static class CacheHelper
4+
{
5+
private const string AuthorizationPayloadKeyFormat = "Umbraco_AuthorizedServices_Payload_{0}";
6+
7+
private const string AuthorizationApiKeyFormat = "Umbraco_AuthorizedServices_ApiKey_{0}";
8+
9+
private const string AuthorizationTokenKeyFormat = "Umbraco_AuthorizedServices_Token_{0}";
10+
11+
private const string AuthorizationTokenSecretFormat = "Umbraco_AuthorizedServices_TokenSecret_{0}";
12+
13+
public static string GetPayloadKey(string serviceAlias) => GetCacheKey(AuthorizationPayloadKeyFormat, serviceAlias);
14+
15+
public static string GetApiKeyCacheKey(string serviceAlias) => GetCacheKey(AuthorizationApiKeyFormat, serviceAlias);
16+
17+
public static string GetTokenCacheKey(string serviceAlias) => GetCacheKey(AuthorizationTokenKeyFormat, serviceAlias);
18+
19+
public static string GetTokenSecretCacheKey(string serviceAlias) => GetCacheKey(AuthorizationTokenSecretFormat, serviceAlias);
20+
21+
private static string GetCacheKey(string format, string serviceAlias) => string.Format(format, serviceAlias);
22+
}
23+
}

src/Umbraco.AuthorizedServices/Services/Implement/AuthorizedServiceAuthorizer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.Extensions.Options;
33
using Umbraco.AuthorizedServices.Configuration;
44
using Umbraco.AuthorizedServices.Exceptions;
5+
using Umbraco.AuthorizedServices.Helpers;
56
using Umbraco.AuthorizedServices.Models;
67
using Umbraco.Cms.Core.Cache;
78
using Umbraco.Extensions;
@@ -63,7 +64,7 @@ public async Task<AuthorizationResult> AuthorizeOAuth1ServiceAsync(string servic
6364
{
6465
ServiceDetail serviceDetail = GetServiceDetail(serviceAlias);
6566

66-
var oauthTokenSecret = AppCaches.RuntimeCache.GetCacheItem($"{serviceDetail.Alias}-oauth-token-secret", () => string.Empty);
67+
var oauthTokenSecret = AppCaches.RuntimeCache.GetCacheItem(CacheHelper.GetTokenSecretCacheKey(serviceDetail.Alias), () => string.Empty);
6768

6869
Dictionary<string, string> parameters = _authorizationParametersBuilder.BuildParametersForOAuth1(serviceDetail, oauthToken, oauthVerifier, oauthTokenSecret ?? string.Empty);
6970

src/Umbraco.AuthorizedServices/Services/Implement/AuthorizedServiceBase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.Extensions.Logging;
22
using Microsoft.Extensions.Options;
33
using Umbraco.AuthorizedServices.Configuration;
4+
using Umbraco.AuthorizedServices.Helpers;
45
using Umbraco.AuthorizedServices.Models;
56
using Umbraco.Cms.Core.Cache;
67
using Umbraco.Extensions;
@@ -63,7 +64,7 @@ protected async Task<OAuth1Token> CreateOAuth1TokenFromResponse(HttpResponseMess
6364
protected void StoreOAuth2Token(string serviceAlias, OAuth2Token token)
6465
{
6566
// Add the access token details to the cache.
66-
var cacheKey = GetTokenCacheKey(serviceAlias);
67+
var cacheKey = CacheHelper.GetTokenCacheKey(serviceAlias);
6768
AppCaches.RuntimeCache.InsertCacheItem(cacheKey, () => token);
6869

6970
// Save the refresh token into the storage.
@@ -75,6 +76,4 @@ protected void StoreOAuth1Token(string serviceAlias, OAuth1Token token)
7576
// Save the token information into the storage.
7677
OAuth1TokenStorage.SaveToken(serviceAlias, token);
7778
}
78-
79-
private static string GetTokenCacheKey(string serviceAlias) => $"Umbraco_AuthorizedServiceToken_{serviceAlias}";
8079
}

src/Umbraco.AuthorizedServices/Services/Implement/AuthorizedServiceCaller.cs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public AuthorizedServiceCaller(
145145
{
146146
var apiKey = !string.IsNullOrEmpty(serviceDetail.ApiKey)
147147
? serviceDetail.ApiKey
148-
: KeyStorage.GetKey(serviceAlias);
148+
: GetApiKeyFromCacheOrStorage(serviceAlias);
149149

150150
if (string.IsNullOrWhiteSpace(apiKey))
151151
{
@@ -314,10 +314,31 @@ private async Task<OAuth2Token> EnsureExchangeAccessToken(string serviceAlias, O
314314
}
315315
}
316316

317+
private string? GetApiKeyFromCacheOrStorage(string serviceAlias)
318+
{
319+
// First look in cache.
320+
var cacheKey = CacheHelper.GetApiKeyCacheKey(serviceAlias);
321+
string? apiKey = AppCaches.RuntimeCache.GetCacheItem<string>(cacheKey);
322+
if (!string.IsNullOrWhiteSpace(apiKey))
323+
{
324+
return apiKey;
325+
}
326+
327+
// Second, look in storage, and if found, save to cache.
328+
apiKey = KeyStorage.GetKey(serviceAlias);
329+
if (!string.IsNullOrWhiteSpace(apiKey))
330+
{
331+
AppCaches.RuntimeCache.InsertCacheItem(cacheKey, () => apiKey);
332+
return apiKey;
333+
}
334+
335+
return null;
336+
}
337+
317338
private OAuth2Token? GetOAuth2TokenFromCacheOrStorage(string serviceAlias)
318339
{
319340
// First look in cache.
320-
var cacheKey = GetTokenCacheKey(serviceAlias);
341+
var cacheKey = CacheHelper.GetTokenCacheKey(serviceAlias);
321342
OAuth2Token? token = AppCaches.RuntimeCache.GetCacheItem<OAuth2Token>(cacheKey);
322343
if (token != null)
323344
{
@@ -338,7 +359,7 @@ private async Task<OAuth2Token> EnsureExchangeAccessToken(string serviceAlias, O
338359
private OAuth1Token? GetOAuth1TokenFromCacheOrStorage(string serviceAlias)
339360
{
340361
// First look in cache.
341-
var cacheKey = GetTokenCacheKey(serviceAlias);
362+
var cacheKey = CacheHelper.GetTokenCacheKey(serviceAlias);
342363
OAuth1Token? token = AppCaches.RuntimeCache.GetCacheItem<OAuth1Token>(cacheKey);
343364
if (token != null)
344365
{
@@ -358,9 +379,8 @@ private async Task<OAuth2Token> EnsureExchangeAccessToken(string serviceAlias, O
358379

359380
private void ClearOAuth2AccessToken(string serviceAlias)
360381
{
361-
AppCaches.RuntimeCache.ClearByKey(GetTokenCacheKey(serviceAlias));
382+
var cacheKey = CacheHelper.GetTokenCacheKey(serviceAlias);
383+
AppCaches.RuntimeCache.ClearByKey(cacheKey);
362384
OAuth2TokenStorage.DeleteToken(serviceAlias);
363385
}
364-
365-
private static string GetTokenCacheKey(string serviceAlias) => string.Format(Constants.Cache.AuthorizationTokenFormat, serviceAlias);
366386
}

0 commit comments

Comments
 (0)