From f503fb7e7a10a8dd86b27111515dda813cdc939c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sun, 11 Feb 2018 05:50:02 +0100 Subject: [PATCH] Cache permissions, redirect_uris and post_logout_redirect_uris in memory --- src/OpenIddict.Core/OpenIddict.Core.csproj | 1 + .../Stores/OpenIddictApplicationStore.cs | 58 ++++++++++++++++++- .../Stores/OpenIddictAuthorizationStore.cs | 16 +++++ .../Stores/OpenIddictScopeStore.cs | 16 +++++ .../Stores/OpenIddictTokenStore.cs | 16 +++++ .../Stores/OpenIddictApplicationStore.cs | 20 ++++++- .../Stores/OpenIddictAuthorizationStore.cs | 20 ++++++- .../Stores/OpenIddictScopeStore.cs | 20 ++++++- .../Stores/OpenIddictTokenStore.cs | 20 ++++++- .../Stores/OpenIddictApplicationStore.cs | 20 ++++++- .../Stores/OpenIddictAuthorizationStore.cs | 20 ++++++- .../Stores/OpenIddictScopeStore.cs | 20 ++++++- .../Stores/OpenIddictTokenStore.cs | 20 ++++++- 13 files changed, 240 insertions(+), 27 deletions(-) diff --git a/src/OpenIddict.Core/OpenIddict.Core.csproj b/src/OpenIddict.Core/OpenIddict.Core.csproj index 36bcb9b4..d283cf18 100644 --- a/src/OpenIddict.Core/OpenIddict.Core.csproj +++ b/src/OpenIddict.Core/OpenIddict.Core.csproj @@ -19,6 +19,7 @@ + diff --git a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs index a42ea82d..715bf9a7 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenIddict.Models; @@ -31,6 +32,21 @@ namespace OpenIddict.Core where TToken : OpenIddictToken, new() where TKey : IEquatable { + protected OpenIddictApplicationStore([NotNull] IMemoryCache cache) + { + if (cache == null) + { + throw new ArgumentNullException(nameof(cache)); + } + + Cache = cache; + } + + /// + /// Gets the memory cached associated with the current store. + /// + protected IMemoryCache Cache { get; } + /// /// Determines the number of applications that exist in the database. /// @@ -350,7 +366,19 @@ namespace OpenIddict.Core return Task.FromResult(ImmutableArray.Create()); } - return Task.FromResult(JArray.Parse(application.Permissions).Select(element => (string) element).ToImmutableArray()); + // Note: parsing the stringified permissions is an expensive operation. + // To mitigate that, the resulting array is stored in the memory cache. + var key = string.Concat(nameof(GetPermissionsAsync), "\x1e", application.Permissions); + + var permissions = Cache.Get(key) as ImmutableArray?; + if (permissions == null) + { + permissions = Cache.Set(key, JArray.Parse(application.Permissions) + .Select(element => (string) element) + .ToImmutableArray()); + } + + return Task.FromResult(permissions.GetValueOrDefault()); } /// @@ -374,7 +402,19 @@ namespace OpenIddict.Core return Task.FromResult(ImmutableArray.Create()); } - return Task.FromResult(JArray.Parse(application.PostLogoutRedirectUris).Select(element => (string) element).ToImmutableArray()); + // Note: parsing the stringified addresses is an expensive operation. + // To mitigate that, the resulting array is stored in the memory cache. + var key = string.Concat(nameof(GetPostLogoutRedirectUrisAsync), "\x1e", application.PostLogoutRedirectUris); + + var addresses = Cache.Get(key) as ImmutableArray?; + if (addresses == null) + { + addresses = Cache.Set(key, JArray.Parse(application.PostLogoutRedirectUris) + .Select(element => (string) element) + .ToImmutableArray()); + } + + return Task.FromResult(addresses.GetValueOrDefault()); } /// @@ -422,7 +462,19 @@ namespace OpenIddict.Core return Task.FromResult(ImmutableArray.Create()); } - return Task.FromResult(JArray.Parse(application.RedirectUris).Select(element => (string) element).ToImmutableArray()); + // Note: parsing the stringified addresses is an expensive operation. + // To mitigate that, the resulting array is stored in the memory cache. + var key = string.Concat(nameof(GetRedirectUrisAsync), "\x1e", application.RedirectUris); + + var addresses = Cache.Get(key) as ImmutableArray?; + if (addresses == null) + { + addresses = Cache.Set(key, JArray.Parse(application.RedirectUris) + .Select(element => (string) element) + .ToImmutableArray()); + } + + return Task.FromResult(addresses.GetValueOrDefault()); } /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs index 1b1e7fb2..147be8f1 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenIddict.Models; @@ -32,6 +33,21 @@ namespace OpenIddict.Core where TToken : OpenIddictToken, new() where TKey : IEquatable { + protected OpenIddictAuthorizationStore([NotNull] IMemoryCache cache) + { + if (cache == null) + { + throw new ArgumentNullException(nameof(cache)); + } + + Cache = cache; + } + + /// + /// Gets the memory cached associated with the current store. + /// + protected IMemoryCache Cache { get; } + /// /// Determines the number of authorizations that exist in the database. /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs index 31128731..31c1c1a2 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenIddict.Models; @@ -27,6 +28,21 @@ namespace OpenIddict.Core where TScope : OpenIddictScope, new() where TKey : IEquatable { + protected OpenIddictScopeStore([NotNull] IMemoryCache cache) + { + if (cache == null) + { + throw new ArgumentNullException(nameof(cache)); + } + + Cache = cache; + } + + /// + /// Gets the memory cached associated with the current store. + /// + protected IMemoryCache Cache { get; } + /// /// Determines the number of scopes that exist in the database. /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs index aaa782df..30db9297 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenIddict.Models; @@ -31,6 +32,21 @@ namespace OpenIddict.Core where TAuthorization : OpenIddictAuthorization, new() where TKey : IEquatable { + protected OpenIddictTokenStore([NotNull] IMemoryCache cache) + { + if (cache == null) + { + throw new ArgumentNullException(nameof(cache)); + } + + Cache = cache; + } + + /// + /// Gets the memory cached associated with the current store. + /// + protected IMemoryCache Cache { get; } + /// /// Determines the number of tokens that exist in the database. /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs index 057b8592..6a1dc4f3 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -27,7 +28,12 @@ namespace OpenIddict.EntityFramework OpenIddictToken, TContext, string> where TContext : DbContext { - public OpenIddictApplicationStore([NotNull] TContext context) : base(context) { } + public OpenIddictApplicationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -42,7 +48,12 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictApplicationStore([NotNull] TContext context) : base(context) { } + public OpenIddictApplicationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -62,7 +73,10 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictApplicationStore([NotNull] TContext context) + public OpenIddictApplicationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs index bf6fe2ed..3430195a 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -27,7 +28,12 @@ namespace OpenIddict.EntityFramework OpenIddictToken, TContext, string> where TContext : DbContext { - public OpenIddictAuthorizationStore([NotNull] TContext context) : base(context) { } + public OpenIddictAuthorizationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -42,7 +48,12 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictAuthorizationStore([NotNull] TContext context) : base(context) { } + public OpenIddictAuthorizationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -62,7 +73,10 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictAuthorizationStore([NotNull] TContext context) + public OpenIddictAuthorizationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs index f1c6bb14..f7459fbd 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -24,7 +25,12 @@ namespace OpenIddict.EntityFramework public class OpenIddictScopeStore : OpenIddictScopeStore where TContext : DbContext { - public OpenIddictScopeStore([NotNull] TContext context) : base(context) { } + public OpenIddictScopeStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -37,7 +43,12 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictScopeStore([NotNull] TContext context) : base(context) { } + public OpenIddictScopeStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -52,7 +63,10 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictScopeStore([NotNull] TContext context) + public OpenIddictScopeStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs index e140c420..14873f05 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -26,7 +27,12 @@ namespace OpenIddict.EntityFramework OpenIddictAuthorization, TContext, string> where TContext : DbContext { - public OpenIddictTokenStore([NotNull] TContext context) : base(context) { } + public OpenIddictTokenStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -41,7 +47,12 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictTokenStore([NotNull] TContext context) : base(context) { } + public OpenIddictTokenStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -61,7 +72,10 @@ namespace OpenIddict.EntityFramework where TContext : DbContext where TKey : IEquatable { - public OpenIddictTokenStore([NotNull] TContext context) + public OpenIddictTokenStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs index 52f03a75..90e723f3 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs @@ -12,6 +12,7 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -27,7 +28,12 @@ namespace OpenIddict.EntityFrameworkCore OpenIddictToken, TContext, string> where TContext : DbContext { - public OpenIddictApplicationStore([NotNull] TContext context) : base(context) { } + public OpenIddictApplicationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -42,7 +48,12 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictApplicationStore([NotNull] TContext context) : base(context) { } + public OpenIddictApplicationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -62,7 +73,10 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictApplicationStore([NotNull] TContext context) + public OpenIddictApplicationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs index 3e9b2bed..db9e18c6 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs @@ -12,6 +12,7 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -27,7 +28,12 @@ namespace OpenIddict.EntityFrameworkCore OpenIddictToken, TContext, string> where TContext : DbContext { - public OpenIddictAuthorizationStore([NotNull] TContext context) : base(context) { } + public OpenIddictAuthorizationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -42,7 +48,12 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictAuthorizationStore([NotNull] TContext context) : base(context) { } + public OpenIddictAuthorizationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -62,7 +73,10 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictAuthorizationStore([NotNull] TContext context) + public OpenIddictAuthorizationStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs index e206da52..018f1b34 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -24,7 +25,12 @@ namespace OpenIddict.EntityFrameworkCore public class OpenIddictScopeStore : OpenIddictScopeStore where TContext : DbContext { - public OpenIddictScopeStore([NotNull] TContext context) : base(context) { } + public OpenIddictScopeStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -37,7 +43,12 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictScopeStore([NotNull] TContext context) : base(context) { } + public OpenIddictScopeStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -52,7 +63,10 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictScopeStore([NotNull] TContext context) + public OpenIddictScopeStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs index 4fc1ed2b..92ab42a2 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; using OpenIddict.Core; using OpenIddict.Models; @@ -26,7 +27,12 @@ namespace OpenIddict.EntityFrameworkCore OpenIddictAuthorization, TContext, string> where TContext : DbContext { - public OpenIddictTokenStore([NotNull] TContext context) : base(context) { } + public OpenIddictTokenStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -41,7 +47,12 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictTokenStore([NotNull] TContext context) : base(context) { } + public OpenIddictTokenStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(context, cache) + { + } } /// @@ -61,7 +72,10 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext where TKey : IEquatable { - public OpenIddictTokenStore([NotNull] TContext context) + public OpenIddictTokenStore( + [NotNull] TContext context, + [NotNull] IMemoryCache cache) + : base(cache) { if (context == null) {