diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index bd2a28f2..a89e4406 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -938,11 +938,21 @@ namespace OpenIddict.Core /// protected virtual async Task ValidateAsync([NotNull] TApplication application, CancellationToken cancellationToken = default) { - if (string.IsNullOrEmpty(await Store.GetClientIdAsync(application, cancellationToken))) + var identifier = await Store.GetClientIdAsync(application, cancellationToken); + if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException("The client identifier cannot be null or empty.", nameof(application)); } + // Ensure the client_id is not already used for a different application. + var other = await Store.FindByClientIdAsync(identifier, cancellationToken); + if (other != null && !string.Equals( + await Store.GetIdAsync(other, cancellationToken), + await Store.GetIdAsync(application, cancellationToken), StringComparison.Ordinal)) + { + throw new ArgumentException("An application with the same client identifier already exists.", nameof(application)); + } + var type = await Store.GetClientTypeAsync(application, cancellationToken); if (string.IsNullOrEmpty(type)) { diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs index 22c793dd..19a9221a 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs @@ -833,6 +833,20 @@ namespace OpenIddict.Core throw new ArgumentNullException(nameof(token)); } + // If a reference identifier was associated with the token, + // ensure it's not already used for a different token. + var identifier = await Store.GetReferenceIdAsync(token, cancellationToken); + if (!string.IsNullOrEmpty(identifier)) + { + var other = await Store.FindByReferenceIdAsync(identifier, cancellationToken); + if (other != null && !string.Equals( + await Store.GetIdAsync(other, cancellationToken), + await Store.GetIdAsync(token, cancellationToken), StringComparison.Ordinal)) + { + throw new ArgumentException("A token with the same reference identifier already exists.", nameof(token)); + } + } + var type = await Store.GetTokenTypeAsync(token, cancellationToken); if (string.IsNullOrEmpty(type)) {