Browse Source

Use unique GUID keys for cache entries to prevent collisions

pull/587/head
Kévin Chalet 8 years ago
parent
commit
d06ca94be2
  1. 20
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
  2. 37
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  3. 16
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
  4. 32
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
  5. 12
      src/OpenIddict.Stores/Stores/OpenIddictApplicationStore.cs
  6. 4
      src/OpenIddict.Stores/Stores/OpenIddictScopeStore.cs

20
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs

@ -250,9 +250,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByClientIdAsync) + "\x1e" + nameof(identifier);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("b7c5b6ad-572f-4106-9a32-4f1dc1981b73", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
@ -281,15 +279,13 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByIdAsync) + "\x1e" + nameof(identifier);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("91082918-b9b9-4701-b969-54e33999a1b9", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id) =>
return EF.CompileAsyncQuery((TContext context, TKey key) =>
(from application in context.Set<TApplication>().AsTracking()
where application.Id.Equals(id)
where application.Id.Equals(key)
select application).FirstOrDefault());
});
@ -312,14 +308,12 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The address cannot be null or empty.", nameof(address));
}
const string key = nameof(FindByPostLogoutRedirectUriAsync) + "\x1e" + nameof(address);
// To optimize the efficiency of the query a bit, only applications whose stringified
// PostLogoutRedirectUris contains the specified URL are returned. Once the applications
// are retrieved, a second pass is made to ensure only valid elements are returned.
// Implementers that use this method in a hot path may want to override this method
// to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("a805ce67-2c5b-4617-a772-56413dccac45", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
@ -367,14 +361,12 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The address cannot be null or empty.", nameof(address));
}
const string key = nameof(FindByRedirectUriAsync) + "\x1e" + nameof(address);
// To optimize the efficiency of the query a bit, only applications whose stringified
// RedirectUris property contains the specified URL are returned. Once the applications
// are retrieved, a second pass is made to ensure only valid elements are returned.
// Implementers that use this method in a hot path may want to override this method
// to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("b3883c99-646f-4027-9855-dad8370b977a", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);

37
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs

@ -235,23 +235,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The client cannot be null or empty.", nameof(client));
}
const string key = nameof(FindAsync) + "\x1e" + nameof(subject) + "\x1e" + nameof(client);
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
// filtered using authorization.Application.Id.Equals(key). To work around this issue,
// this method is overriden to use an explicit join before applying the equality check.
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("a3235f5b-2be5-452e-a43e-b10f5d6a01ff", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id, string principal) =>
return EF.CompileAsyncQuery((TContext context, TKey key, string principal) =>
from authorization in context.Set<TAuthorization>()
.Include(authorization => authorization.Application)
.AsTracking()
where authorization.Subject == principal
join application in context.Set<TApplication>().AsTracking() on authorization.Application.Id equals application.Id
where application.Id.Equals(id)
where application.Id.Equals(key)
select authorization);
});
@ -289,23 +287,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The status cannot be null or empty.", nameof(status));
}
const string key = nameof(FindAsync) + "\x1e" + nameof(subject) + "\x1e" + nameof(client) + "\x1e" + nameof(status);
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
// filtered using authorization.Application.Id.Equals(key). To work around this issue,
// this method is overriden to use an explicit join before applying the equality check.
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("bdf6b8aa-cd27-4b23-9961-fdd896a6660e", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id, string principal, string state) =>
return EF.CompileAsyncQuery((TContext context, TKey key, string principal, string state) =>
from authorization in context.Set<TAuthorization>()
.Include(authorization => authorization.Application)
.AsTracking()
where authorization.Subject == principal && authorization.Status == state
join application in context.Set<TApplication>().AsTracking() on authorization.Application.Id equals application.Id
where application.Id.Equals(id)
where application.Id.Equals(key)
select authorization);
});
@ -349,18 +345,15 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The type cannot be null or empty.", nameof(type));
}
const string key = nameof(FindAsync) + "\x1e" + nameof(subject) + "\x1e" +
nameof(client) + "\x1e" + nameof(status) + "\x1e" + nameof(type);
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
// filtered using authorization.Application.Id.Equals(key). To work around this issue,
// this method is overriden to use an explicit join before applying the equality check.
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("5d06e679-70cd-4f4b-94f7-19ffe9d5d8ab", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id, string principal, string state, string kind) =>
return EF.CompileAsyncQuery((TContext context, TKey key, string principal, string state, string kind) =>
from authorization in context.Set<TAuthorization>()
.Include(authorization => authorization.Application)
.AsTracking()
@ -368,7 +361,7 @@ namespace OpenIddict.EntityFrameworkCore
authorization.Status == state &&
authorization.Type == kind
join application in context.Set<TApplication>().AsTracking() on authorization.Application.Id equals application.Id
where application.Id.Equals(id)
where application.Id.Equals(key)
select authorization);
});
@ -392,17 +385,15 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByIdAsync) + "\x1e" + nameof(identifier);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("0f00e136-9277-484a-8ee4-12bf1d889c43", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id) =>
return EF.CompileAsyncQuery((TContext context, TKey key) =>
(from authorization in context.Set<TAuthorization>()
.Include(authorization => authorization.Application)
.AsTracking()
where authorization.Id.Equals(id)
where authorization.Id.Equals(key)
select authorization).FirstOrDefault());
});
@ -426,9 +417,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
}
const string key = nameof(FindBySubjectAsync) + "\x1e" + nameof(subject);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("31e53867-fa49-4d1b-b846-acce353acd0b", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);

16
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs

@ -155,15 +155,13 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByIdAsync) + "\x1e" + nameof(identifier);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("485f3372-2d38-4418-8d1e-acd8aa0c3555", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id) =>
return EF.CompileAsyncQuery((TContext context, TKey key) =>
(from scope in context.Set<TScope>().AsTracking()
where scope.Id.Equals(id)
where scope.Id.Equals(key)
select scope).FirstOrDefault());
});
@ -186,9 +184,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The scope name cannot be null or empty.", nameof(name));
}
const string key = nameof(FindByNameAsync) + "\x1e" + nameof(name);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("71cb2f7a-7adb-4b3e-8833-772e254f9b03", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
@ -218,9 +214,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("Scope names cannot be null or empty.", nameof(names));
}
const string key = nameof(FindByNamesAsync) + "\x1e" + nameof(names);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("e19404af-8586-4693-9b9c-8185b653ee2d", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);

32
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

@ -178,23 +178,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByApplicationIdAsync) + "\x1e" + nameof(identifier);
// Note: due to a bug in Entity Framework Core's query visitor, the tokens can't be
// filtered using token.Application.Id.Equals(key). To work around this issue,
// this method is overriden to use an explicit join before applying the equality check.
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("9c2e8fed-053a-477c-be42-ec4037109be6", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id) =>
return EF.CompileAsyncQuery((TContext context, TKey key) =>
from token in context.Set<TToken>()
.Include(token => token.Application)
.Include(token => token.Authorization)
.AsTracking()
join application in context.Set<TApplication>().AsTracking() on token.Application.Id equals application.Id
where application.Id.Equals(id)
where application.Id.Equals(key)
select token);
});
@ -218,23 +216,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByAuthorizationIdAsync) + "\x1e" + nameof(identifier);
// Note: due to a bug in Entity Framework Core's query visitor, the tokens can't be
// filtered using token.Authorization.Id.Equals(key). To work around this issue,
// this method is overriden to use an explicit join before applying the equality check.
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("bfc92016-710f-492b-bcf0-48452a832950", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery<TContext, TKey, TToken>((TContext context, TKey id) =>
return EF.CompileAsyncQuery((TContext context, TKey key) =>
from token in context.Set<TToken>()
.Include(token => token.Application)
.Include(token => token.Authorization)
.AsTracking()
join authorization in context.Set<TAuthorization>().AsTracking() on token.Authorization.Id equals authorization.Id
where authorization.Id.Equals(id)
where authorization.Id.Equals(key)
select token);
});
@ -258,18 +254,16 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByIdAsync) + "\x1e" + nameof(identifier);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("a311088f-3b26-4ca7-bbe5-6194d3375777", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
return EF.CompileAsyncQuery((TContext context, TKey id) =>
return EF.CompileAsyncQuery((TContext context, TKey key) =>
(from token in context.Set<TToken>()
.Include(token => token.Application)
.Include(token => token.Authorization)
.AsTracking()
where token.Id.Equals(id)
where token.Id.Equals(key)
select token).FirstOrDefault());
});
@ -293,9 +287,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
const string key = nameof(FindByReferenceIdAsync) + "\x1e" + nameof(identifier);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("26fd749d-9198-466a-b78e-afbc1b4d89d3", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);
@ -327,9 +319,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
}
const string key = nameof(FindBySubjectAsync) + "\x1e" + nameof(subject);
var query = Cache.GetOrCreate(key, entry =>
var query = Cache.GetOrCreate("61a80b05-d069-4e05-b2e2-66d4bc89b492", entry =>
{
entry.SetPriority(CacheItemPriority.NeverRemove);

12
src/OpenIddict.Stores/Stores/OpenIddictApplicationStore.cs

@ -392,9 +392,7 @@ namespace OpenIddict.Stores
// 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.GetOrCreate(key, entry =>
var permissions = Cache.GetOrCreate("0347e0aa-3a26-410a-97e8-a83bdeb21a1f", entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
@ -430,9 +428,7 @@ namespace OpenIddict.Stores
// 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.GetOrCreate(key, entry =>
var addresses = Cache.GetOrCreate("fb14dfb9-9216-4b77-bfa9-7e85f8201ff4", entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
@ -492,9 +488,7 @@ namespace OpenIddict.Stores
// 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.GetOrCreate(key, entry =>
var addresses = Cache.GetOrCreate("851d6f08-2ee0-4452-bbe5-ab864611ecaa", entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));

4
src/OpenIddict.Stores/Stores/OpenIddictScopeStore.cs

@ -301,9 +301,7 @@ namespace OpenIddict.Stores
// Note: parsing the stringified resources is an expensive operation.
// To mitigate that, the resulting array is stored in the memory cache.
var key = string.Concat(nameof(GetResourcesAsync), "\x1e", scope.Resources);
var resources = Cache.GetOrCreate(key, entry =>
var resources = Cache.GetOrCreate("b6148250-aede-4fb9-a621-07c9bcf238c3", entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));

Loading…
Cancel
Save