diff --git a/src/OpenIddict.Abstractions/Descriptors/OpenIddictApplicationDescriptor.cs b/src/OpenIddict.Abstractions/Descriptors/OpenIddictApplicationDescriptor.cs
index 399397d7..b1638f1b 100644
--- a/src/OpenIddict.Abstractions/Descriptors/OpenIddictApplicationDescriptor.cs
+++ b/src/OpenIddict.Abstractions/Descriptors/OpenIddictApplicationDescriptor.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Text.Json;
namespace OpenIddict.Abstractions
{
@@ -34,28 +35,32 @@ namespace OpenIddict.Abstractions
///
/// Gets the localized display names associated with the application.
///
- public Dictionary DisplayNames { get; }
- = new Dictionary();
+ public Dictionary DisplayNames { get; } = new();
///
/// Gets the permissions associated with the application.
///
- public HashSet Permissions { get; } = new HashSet(StringComparer.Ordinal);
+ public HashSet Permissions { get; } = new(StringComparer.Ordinal);
///
/// Gets the logout callback URLs associated with the application.
///
- public HashSet PostLogoutRedirectUris { get; } = new HashSet();
+ public HashSet PostLogoutRedirectUris { get; } = new();
+
+ ///
+ /// Gets the additional properties associated with the application.
+ ///
+ public Dictionary Properties { get; } = new(StringComparer.Ordinal);
///
/// Gets the callback URLs associated with the application.
///
- public HashSet RedirectUris { get; } = new HashSet();
+ public HashSet RedirectUris { get; } = new();
///
/// Gets the requirements associated with the application.
///
- public HashSet Requirements { get; } = new HashSet(StringComparer.Ordinal);
+ public HashSet Requirements { get; } = new(StringComparer.Ordinal);
///
/// Gets or sets the application type associated with the application.
diff --git a/src/OpenIddict.Abstractions/Descriptors/OpenIddictAuthorizationDescriptor.cs b/src/OpenIddict.Abstractions/Descriptors/OpenIddictAuthorizationDescriptor.cs
index 88563153..9c038894 100644
--- a/src/OpenIddict.Abstractions/Descriptors/OpenIddictAuthorizationDescriptor.cs
+++ b/src/OpenIddict.Abstractions/Descriptors/OpenIddictAuthorizationDescriptor.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
+using System.Text.Json;
namespace OpenIddict.Abstractions
{
@@ -25,10 +26,15 @@ namespace OpenIddict.Abstractions
///
public ClaimsPrincipal? Principal { get; set; }
+ ///
+ /// Gets the additional properties associated with the authorization.
+ ///
+ public Dictionary Properties { get; } = new(StringComparer.Ordinal);
+
///
/// Gets the scopes associated with the authorization.
///
- public HashSet Scopes { get; } = new HashSet(StringComparer.Ordinal);
+ public HashSet Scopes { get; } = new(StringComparer.Ordinal);
///
/// Gets or sets the status associated with the authorization.
diff --git a/src/OpenIddict.Abstractions/Descriptors/OpenIddictScopeDescriptor.cs b/src/OpenIddict.Abstractions/Descriptors/OpenIddictScopeDescriptor.cs
index 3ea35327..69ba8f5b 100644
--- a/src/OpenIddict.Abstractions/Descriptors/OpenIddictScopeDescriptor.cs
+++ b/src/OpenIddict.Abstractions/Descriptors/OpenIddictScopeDescriptor.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Text.Json;
namespace OpenIddict.Abstractions
{
@@ -17,7 +18,7 @@ namespace OpenIddict.Abstractions
///
/// Gets the localized descriptions associated with the scope.
///
- public Dictionary Descriptions { get; } = new Dictionary();
+ public Dictionary Descriptions { get; } = new();
///
/// Gets or sets the display name associated with the scope.
@@ -27,16 +28,21 @@ namespace OpenIddict.Abstractions
///
/// Gets the localized display names associated with the scope.
///
- public Dictionary DisplayNames { get; } = new Dictionary();
+ public Dictionary DisplayNames { get; } = new();
///
/// Gets or sets the unique name associated with the scope.
///
public string? Name { get; set; }
+ ///
+ /// Gets the additional properties associated with the scope.
+ ///
+ public Dictionary Properties { get; } = new(StringComparer.Ordinal);
+
///
/// Gets the resources associated with the scope.
///
- public HashSet Resources { get; } = new HashSet(StringComparer.Ordinal);
+ public HashSet Resources { get; } = new(StringComparer.Ordinal);
}
}
diff --git a/src/OpenIddict.Abstractions/Descriptors/OpenIddictTokenDescriptor.cs b/src/OpenIddict.Abstractions/Descriptors/OpenIddictTokenDescriptor.cs
index f75d81f7..4c931407 100644
--- a/src/OpenIddict.Abstractions/Descriptors/OpenIddictTokenDescriptor.cs
+++ b/src/OpenIddict.Abstractions/Descriptors/OpenIddictTokenDescriptor.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using System.Security.Claims;
+using System.Text.Json;
namespace OpenIddict.Abstractions
{
@@ -39,6 +41,11 @@ namespace OpenIddict.Abstractions
///
public ClaimsPrincipal? Principal { get; set; }
+ ///
+ /// Gets the additional properties associated with the token.
+ ///
+ public Dictionary Properties { get; } = new(StringComparer.Ordinal);
+
///
/// Gets or sets the redemption date associated with the token.
///
diff --git a/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs b/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs
index a9ffaea0..be956652 100644
--- a/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs
+++ b/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs
@@ -10,6 +10,7 @@ using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -275,6 +276,17 @@ namespace OpenIddict.Abstractions
///
ValueTask> GetPostLogoutRedirectUrisAsync(object application, CancellationToken cancellationToken = default);
+ ///
+ /// Retrieves the additional properties associated with an application.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the application.
+ ///
+ ValueTask> GetPropertiesAsync(object application, CancellationToken cancellationToken = default);
+
///
/// Retrieves the callback addresses associated with an application.
///
diff --git a/src/OpenIddict.Abstractions/Managers/IOpenIddictAuthorizationManager.cs b/src/OpenIddict.Abstractions/Managers/IOpenIddictAuthorizationManager.cs
index d8824a97..44d5e22f 100644
--- a/src/OpenIddict.Abstractions/Managers/IOpenIddictAuthorizationManager.cs
+++ b/src/OpenIddict.Abstractions/Managers/IOpenIddictAuthorizationManager.cs
@@ -10,6 +10,7 @@ using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Claims;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -232,6 +233,17 @@ namespace OpenIddict.Abstractions
///
ValueTask GetIdAsync(object authorization, CancellationToken cancellationToken = default);
+ ///
+ /// Retrieves the additional properties associated with an authorization.
+ ///
+ /// The authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the authorization.
+ ///
+ ValueTask> GetPropertiesAsync(object authorization, CancellationToken cancellationToken = default);
+
///
/// Retrieves the scopes associated with an authorization.
///
diff --git a/src/OpenIddict.Abstractions/Managers/IOpenIddictScopeManager.cs b/src/OpenIddict.Abstractions/Managers/IOpenIddictScopeManager.cs
index d9107d94..bcfb9cd7 100644
--- a/src/OpenIddict.Abstractions/Managers/IOpenIddictScopeManager.cs
+++ b/src/OpenIddict.Abstractions/Managers/IOpenIddictScopeManager.cs
@@ -10,6 +10,7 @@ using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -264,6 +265,17 @@ namespace OpenIddict.Abstractions
///
ValueTask GetNameAsync(object scope, CancellationToken cancellationToken = default);
+ ///
+ /// Retrieves the additional properties associated with a scope.
+ ///
+ /// The scope.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the scope.
+ ///
+ ValueTask> GetPropertiesAsync(object scope, CancellationToken cancellationToken = default);
+
///
/// Retrieves the resources associated with a scope.
///
diff --git a/src/OpenIddict.Abstractions/Managers/IOpenIddictTokenManager.cs b/src/OpenIddict.Abstractions/Managers/IOpenIddictTokenManager.cs
index 1acfe65c..d3d2cb43 100644
--- a/src/OpenIddict.Abstractions/Managers/IOpenIddictTokenManager.cs
+++ b/src/OpenIddict.Abstractions/Managers/IOpenIddictTokenManager.cs
@@ -6,8 +6,10 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Linq;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -253,6 +255,17 @@ namespace OpenIddict.Abstractions
///
ValueTask GetPayloadAsync(object token, CancellationToken cancellationToken = default);
+ ///
+ /// Retrieves the additional properties associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the token.
+ ///
+ ValueTask> GetPropertiesAsync(object token, CancellationToken cancellationToken = default);
+
///
/// Retrieves the redemption date associated with a token.
///
diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
index ee0d18c4..db0eb6dd 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
@@ -15,6 +15,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -696,6 +697,26 @@ namespace OpenIddict.Core
return Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken);
}
+ ///
+ /// Retrieves the additional properties associated with an application.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the application.
+ ///
+ public virtual ValueTask> GetPropertiesAsync(
+ TApplication application, CancellationToken cancellationToken = default)
+ {
+ if (application is null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Store.GetPropertiesAsync(application, cancellationToken);
+ }
+
///
/// Retrieves the callback addresses associated with an application.
///
@@ -909,6 +930,7 @@ namespace OpenIddict.Core
await Store.SetPermissionsAsync(application, descriptor.Permissions.ToImmutableArray(), cancellationToken);
await Store.SetPostLogoutRedirectUrisAsync(application, ImmutableArray.CreateRange(
descriptor.PostLogoutRedirectUris.Select(address => address.OriginalString)), cancellationToken);
+ await Store.SetPropertiesAsync(application, descriptor.Properties.ToImmutableDictionary(), cancellationToken);
await Store.SetRedirectUrisAsync(application, ImmutableArray.CreateRange(
descriptor.RedirectUris.Select(address => address.OriginalString)), cancellationToken);
await Store.SetRequirementsAsync(application, descriptor.Requirements.ToImmutableArray(), cancellationToken);
@@ -971,6 +993,12 @@ namespace OpenIddict.Core
descriptor.PostLogoutRedirectUris.Add(uri);
}
+ descriptor.Properties.Clear();
+ foreach (var pair in await Store.GetPropertiesAsync(application, cancellationToken))
+ {
+ descriptor.Properties.Add(pair.Key, pair.Value);
+ }
+
descriptor.RedirectUris.Clear();
foreach (var address in await Store.GetRedirectUrisAsync(application, cancellationToken))
{
@@ -1581,6 +1609,10 @@ namespace OpenIddict.Core
ValueTask> IOpenIddictApplicationManager.GetPostLogoutRedirectUrisAsync(object application, CancellationToken cancellationToken)
=> GetPostLogoutRedirectUrisAsync((TApplication) application, cancellationToken);
+ ///
+ ValueTask> IOpenIddictApplicationManager.GetPropertiesAsync(object application, CancellationToken cancellationToken)
+ => GetPropertiesAsync((TApplication) application, cancellationToken);
+
///
ValueTask> IOpenIddictApplicationManager.GetRedirectUrisAsync(object application, CancellationToken cancellationToken)
=> GetRedirectUrisAsync((TApplication) application, cancellationToken);
diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
index 3851ff2a..2ee0b741 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
@@ -12,6 +12,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Text;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -714,6 +715,26 @@ namespace OpenIddict.Core
return Store.GetIdAsync(authorization, cancellationToken);
}
+ ///
+ /// Retrieves the additional properties associated with an authorization.
+ ///
+ /// The authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the authorization.
+ ///
+ public virtual ValueTask> GetPropertiesAsync(
+ TAuthorization authorization, CancellationToken cancellationToken = default)
+ {
+ if (authorization is null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ return Store.GetPropertiesAsync(authorization, cancellationToken);
+ }
+
///
/// Retrieves the scopes associated with an authorization.
///
@@ -933,6 +954,7 @@ namespace OpenIddict.Core
await Store.SetApplicationIdAsync(authorization, descriptor.ApplicationId, cancellationToken);
await Store.SetCreationDateAsync(authorization, descriptor.CreationDate, cancellationToken);
+ await Store.SetPropertiesAsync(authorization, descriptor.Properties.ToImmutableDictionary(), cancellationToken);
await Store.SetScopesAsync(authorization, descriptor.Scopes.ToImmutableArray(), cancellationToken);
await Store.SetStatusAsync(authorization, descriptor.Status, cancellationToken);
await Store.SetSubjectAsync(authorization, descriptor.Subject, cancellationToken);
@@ -969,6 +991,12 @@ namespace OpenIddict.Core
descriptor.Status = await Store.GetStatusAsync(authorization, cancellationToken);
descriptor.Subject = await Store.GetSubjectAsync(authorization, cancellationToken);
descriptor.Type = await Store.GetTypeAsync(authorization, cancellationToken);
+
+ descriptor.Properties.Clear();
+ foreach (var pair in await Store.GetPropertiesAsync(authorization, cancellationToken))
+ {
+ descriptor.Properties.Add(pair.Key, pair.Value);
+ }
}
///
@@ -1231,6 +1259,10 @@ namespace OpenIddict.Core
ValueTask IOpenIddictAuthorizationManager.GetIdAsync(object authorization, CancellationToken cancellationToken)
=> GetIdAsync((TAuthorization) authorization, cancellationToken);
+ ///
+ ValueTask> IOpenIddictAuthorizationManager.GetPropertiesAsync(object authorization, CancellationToken cancellationToken)
+ => GetPropertiesAsync((TAuthorization) authorization, cancellationToken);
+
///
ValueTask> IOpenIddictAuthorizationManager.GetScopesAsync(object authorization, CancellationToken cancellationToken)
=> GetScopesAsync((TAuthorization) authorization, cancellationToken);
diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
index 77acd25e..ea7d9ca5 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
@@ -12,6 +12,7 @@ using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -650,6 +651,26 @@ namespace OpenIddict.Core
return Store.GetNameAsync(scope, cancellationToken);
}
+ ///
+ /// Retrieves the additional properties associated with a scope.
+ ///
+ /// The scope.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the scope.
+ ///
+ public virtual ValueTask> GetPropertiesAsync(
+ TScope scope, CancellationToken cancellationToken = default)
+ {
+ if (scope is null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ return Store.GetPropertiesAsync(scope, cancellationToken);
+ }
+
///
/// Retrieves the resources associated with a scope.
///
@@ -769,6 +790,7 @@ namespace OpenIddict.Core
await Store.SetDisplayNameAsync(scope, descriptor.DisplayName, cancellationToken);
await Store.SetDisplayNamesAsync(scope, descriptor.DisplayNames.ToImmutableDictionary(), cancellationToken);
await Store.SetNameAsync(scope, descriptor.Name, cancellationToken);
+ await Store.SetPropertiesAsync(scope, descriptor.Properties.ToImmutableDictionary(), cancellationToken);
await Store.SetResourcesAsync(scope, descriptor.Resources.ToImmutableArray(), cancellationToken);
}
@@ -812,6 +834,12 @@ namespace OpenIddict.Core
{
descriptor.Descriptions.Add(pair.Key, pair.Value);
}
+
+ descriptor.Properties.Clear();
+ foreach (var pair in await Store.GetPropertiesAsync(scope, cancellationToken))
+ {
+ descriptor.Properties.Add(pair.Key, pair.Value);
+ }
}
///
@@ -1019,6 +1047,10 @@ namespace OpenIddict.Core
ValueTask IOpenIddictScopeManager.GetNameAsync(object scope, CancellationToken cancellationToken)
=> GetNameAsync((TScope) scope, cancellationToken);
+ ///
+ ValueTask> IOpenIddictScopeManager.GetPropertiesAsync(object scope, CancellationToken cancellationToken)
+ => GetPropertiesAsync((TScope) scope, cancellationToken);
+
///
ValueTask> IOpenIddictScopeManager.GetResourcesAsync(object scope, CancellationToken cancellationToken)
=> GetResourcesAsync((TScope) scope, cancellationToken);
diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
index 7282a343..dc5f363a 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
@@ -12,6 +12,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -736,6 +737,26 @@ namespace OpenIddict.Core
return Store.GetPayloadAsync(token, cancellationToken);
}
+ ///
+ /// Retrieves the additional properties associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the additional properties associated with the token.
+ ///
+ public virtual ValueTask> GetPropertiesAsync(
+ TToken token, CancellationToken cancellationToken = default)
+ {
+ if (token is null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Store.GetPropertiesAsync(token, cancellationToken);
+ }
+
///
/// Retrieves the redemption date associated with a token.
///
@@ -954,6 +975,7 @@ namespace OpenIddict.Core
await Store.SetCreationDateAsync(token, descriptor.CreationDate, cancellationToken);
await Store.SetExpirationDateAsync(token, descriptor.ExpirationDate, cancellationToken);
await Store.SetPayloadAsync(token, descriptor.Payload, cancellationToken);
+ await Store.SetPropertiesAsync(token, descriptor.Properties.ToImmutableDictionary(), cancellationToken);
await Store.SetRedemptionDateAsync(token, descriptor.RedemptionDate, cancellationToken);
await Store.SetReferenceIdAsync(token, descriptor.ReferenceId, cancellationToken);
await Store.SetStatusAsync(token, descriptor.Status, cancellationToken);
@@ -994,6 +1016,12 @@ namespace OpenIddict.Core
descriptor.Status = await Store.GetStatusAsync(token, cancellationToken);
descriptor.Subject = await Store.GetSubjectAsync(token, cancellationToken);
descriptor.Type = await Store.GetTypeAsync(token, cancellationToken);
+
+ descriptor.Properties.Clear();
+ foreach (var pair in await Store.GetPropertiesAsync(token, cancellationToken))
+ {
+ descriptor.Properties.Add(pair.Key, pair.Value);
+ }
}
///
@@ -1370,6 +1398,10 @@ namespace OpenIddict.Core
ValueTask IOpenIddictTokenManager.GetPayloadAsync(object token, CancellationToken cancellationToken)
=> GetPayloadAsync((TToken) token, cancellationToken);
+ ///
+ ValueTask> IOpenIddictTokenManager.GetPropertiesAsync(object token, CancellationToken cancellationToken)
+ => GetPropertiesAsync((TToken) token, cancellationToken);
+
///
ValueTask IOpenIddictTokenManager.GetRedemptionDateAsync(object token, CancellationToken cancellationToken)
=> GetRedemptionDateAsync((TToken) token, cancellationToken);