diff --git a/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx b/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
index c1ca8120..e707e673 100644
--- a/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
+++ b/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
@@ -2184,18 +2184,10 @@ The principal used to create the token contained the following claims: {Claims}.
The introspection request was rejected because the received token was of an unsupported type.
{Locked}
-
- The introspection request was rejected because the authorization code was issued to a different client.
- {Locked}
-
The introspection request was rejected because the access token was issued to a different client or for another resource server.
{Locked}
-
- The introspection request was rejected because the identity token was issued to a different client.
- {Locked}
-
The introspection request was rejected because the refresh token was issued to a different client.
{Locked}
@@ -2236,18 +2228,10 @@ The principal used to create the token contained the following claims: {Claims}.
The revocation request was rejected because the received token was of an unsupported type.
{Locked}
-
- The revocation request was rejected because the authorization code was issued to a different client.
- {Locked}
-
The revocation request was rejected because the access token was issued to a different client or for another resource server.
{Locked}
-
- The revocation request was rejected because the identity token was issued to a different client.
- {Locked}
-
The revocation request was rejected because the refresh token was issued to a different client.
{Locked}
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
index f9c9437f..e57c08b9 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
@@ -741,8 +741,6 @@ namespace OpenIddict.Server
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
- !context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) &&
- !context.Principal.HasTokenType(TokenTypeHints.IdToken) &&
!context.Principal.HasTokenType(TokenTypeHints.RefreshToken))
{
context.Logger.LogError(SR.GetResourceString(SR.ID7104));
@@ -789,29 +787,6 @@ namespace OpenIddict.Server
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
- // When the introspected token is an authorization code, the caller must be
- // listed as a presenter (i.e the party the authorization code was issued to).
- if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode))
- {
- if (!context.Principal.HasPresenter())
- {
- throw new InvalidOperationException(SR.GetResourceString(SR.ID1042));
- }
-
- if (!context.Principal.HasPresenter(context.ClientId))
- {
- context.Logger.LogError(SR.GetResourceString(SR.ID7105));
-
- context.Reject(
- error: Errors.InvalidToken,
- description: context.Localizer[SR.ID3077]);
-
- return default;
- }
-
- return default;
- }
-
// When the introspected token is an access token, the caller must be listed either as a presenter
// (i.e the party the token was issued to) or as an audience (i.e a resource server/API).
// If the access token doesn't contain any explicit presenter/audience, the token is assumed
@@ -829,22 +804,6 @@ namespace OpenIddict.Server
return default;
}
- // When the introspected token is an identity token, the caller must be listed as an audience
- // (i.e the client application the identity token was initially issued to).
- // If the identity token doesn't contain any explicit audience, the token is
- // assumed to be not specific to any client application and the check is bypassed.
- if (context.Principal.HasTokenType(TokenTypeHints.IdToken) &&
- context.Principal.HasAudience() && !context.Principal.HasAudience(context.ClientId))
- {
- context.Logger.LogError(SR.GetResourceString(SR.ID7107));
-
- context.Reject(
- error: Errors.InvalidToken,
- description: context.Localizer[SR.ID3077]);
-
- return default;
- }
-
// When the introspected token is a refresh token, the caller must be
// listed as a presenter (i.e the party the token was issued to).
// If the refresh token doesn't contain any explicit presenter, the token is
@@ -985,8 +944,8 @@ namespace OpenIddict.Server
Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), SR.FormatID5000(Parameters.ClientId));
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
- // Don't return application-specific claims if the token is not an access or identity token.
- if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) && !context.Principal.HasTokenType(TokenTypeHints.IdToken))
+ // Don't return application-specific claims if the token is not an access token.
+ if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken))
{
return;
}
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
index e661341a..ac50598e 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
@@ -687,7 +687,6 @@ namespace OpenIddict.Server
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
- !context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) &&
!context.Principal.HasTokenType(TokenTypeHints.RefreshToken))
{
context.Logger.LogError(SR.GetResourceString(SR.ID7117));
@@ -734,29 +733,6 @@ namespace OpenIddict.Server
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
- // When the revoked token is an authorization code, the caller must be
- // listed as a presenter (i.e the party the authorization code was issued to).
- if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode))
- {
- if (!context.Principal.HasPresenter())
- {
- throw new InvalidOperationException(SR.GetResourceString(SR.ID1042));
- }
-
- if (!context.Principal.HasPresenter(context.ClientId))
- {
- context.Logger.LogError(SR.GetResourceString(SR.ID7118));
-
- context.Reject(
- error: Errors.InvalidToken,
- description: context.Localizer[SR.ID3080]);
-
- return default;
- }
-
- return default;
- }
-
// When the revoked token is an access token, the caller must be listed either as a presenter
// (i.e the party the token was issued to) or as an audience (i.e a resource server/API).
// If the access token doesn't contain any explicit presenter/audience, the token is assumed
@@ -774,22 +750,6 @@ namespace OpenIddict.Server
return default;
}
- // When the revoked token is an identity token, the caller must be listed as an audience
- // (i.e the client application the identity token was initially issued to).
- // If the identity token doesn't contain any explicit audience, the token is
- // assumed to be not specific to any client application and the check is bypassed.
- if (context.Principal.HasTokenType(TokenTypeHints.IdToken) &&
- context.Principal.HasAudience() && !context.Principal.HasAudience(context.ClientId))
- {
- context.Logger.LogError(SR.GetResourceString(SR.ID7120));
-
- context.Reject(
- error: Errors.InvalidToken,
- description: context.Localizer[SR.ID3080]);
-
- return default;
- }
-
// When the revoked token is a refresh token, the caller must be
// listed as a presenter (i.e the party the token was issued to).
// If the refresh token doesn't contain any explicit presenter, the token is
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs
index 0e257478..a95f39be 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs
@@ -5,7 +5,6 @@
*/
using System;
-using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Text.Json;
@@ -221,49 +220,13 @@ namespace OpenIddict.Server.IntegrationTests
Assert.Equal(SR.GetResourceString(SR.ID3019), response.ErrorDescription);
}
- [Fact]
- public async Task ValidateIntrospectionRequest_AuthorizationCodeCausesAnErrorWhenPresentersAreMissing()
- {
- // Arrange
- await using var server = await CreateServerAsync(options =>
- {
- options.EnableDegradedMode();
-
- options.AddEventHandler(builder =>
- {
- builder.UseInlineHandler(context =>
- {
- Assert.Equal("SlAV32hkKG", context.Token);
-
- context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.AuthorizationCode)
- .SetPresenters(Enumerable.Empty());
-
- return default;
- });
-
- builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
- });
- });
-
- await using var client = await server.CreateClientAsync();
-
- // Act and assert
- var exception = await Assert.ThrowsAsync(delegate
- {
- return client.PostAsync("/connect/introspect", new OpenIddictRequest
- {
- ClientId = "Fabrikam",
- Token = "SlAV32hkKG",
- TokenTypeHint = TokenTypeHints.AuthorizationCode
- });
- });
-
- Assert.Equal(SR.GetResourceString(SR.ID1042), exception.Message);
- }
-
- [Fact]
- public async Task ValidateIntrospectionRequest_AuthorizationCodeCausesAnErrorWhenCallerIsNotAValidPresenter()
+ [Theory]
+ [InlineData(TokenTypeHints.AuthorizationCode)]
+ [InlineData(TokenTypeHints.DeviceCode)]
+ [InlineData(TokenTypeHints.IdToken)]
+ [InlineData(TokenTypeHints.UserCode)]
+ [InlineData("custom_token")]
+ public async Task ValidateIntrospectionRequest_UnsupportedTokenTypeCausesAnError(string type)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@@ -274,11 +237,10 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
- Assert.Equal("SlAV32hkKG", context.Token);
+ Assert.Equal("5HtRgAtc02", context.Token);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.AuthorizationCode)
- .SetPresenters("Contoso");
+ .SetTokenType(type);
return default;
});
@@ -295,13 +257,12 @@ namespace OpenIddict.Server.IntegrationTests
var response = await client.PostAsync("/connect/introspect", new OpenIddictRequest
{
ClientId = "Fabrikam",
- Token = "SlAV32hkKG",
- TokenTypeHint = TokenTypeHints.AuthorizationCode
+ Token = "5HtRgAtc02"
});
// Assert
- Assert.Equal(Errors.InvalidToken, response.Error);
- Assert.Equal(SR.GetResourceString(SR.ID3077), response.ErrorDescription);
+ Assert.Equal(Errors.UnsupportedTokenType, response.Error);
+ Assert.Equal(SR.GetResourceString(SR.ID3076), response.ErrorDescription);
}
[Fact]
@@ -347,48 +308,6 @@ namespace OpenIddict.Server.IntegrationTests
Assert.Equal(SR.GetResourceString(SR.ID3077), response.ErrorDescription);
}
- [Fact]
- public async Task ValidateIntrospectionRequest_IdentityTokenCausesAnErrorWhenCallerIsNotAValidAudience()
- {
- // Arrange
- await using var server = await CreateServerAsync(options =>
- {
- options.EnableDegradedMode();
-
- options.AddEventHandler(builder =>
- {
- builder.UseInlineHandler(context =>
- {
- Assert.Equal("2YotnFZFEjr1zCsicMWpAA", context.Token);
-
- context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.IdToken)
- .SetAudiences("AdventureWorks");
-
- return default;
- });
-
- builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
- });
-
- options.RemoveEventHandler(NormalizeErrorResponse.Descriptor);
- });
-
- await using var client = await server.CreateClientAsync();
-
- // Act
- var response = await client.PostAsync("/connect/introspect", new OpenIddictRequest
- {
- ClientId = "Fabrikam",
- Token = "2YotnFZFEjr1zCsicMWpAA",
- TokenTypeHint = TokenTypeHints.IdToken
- });
-
- // Assert
- Assert.Equal(Errors.InvalidToken, response.Error);
- Assert.Equal(SR.GetResourceString(SR.ID3077), response.ErrorDescription);
- }
-
[Fact]
public async Task ValidateIntrospectionRequest_RefreshTokenCausesAnErrorWhenCallerIsNotAValidPresenter()
{
@@ -847,49 +766,6 @@ namespace OpenIddict.Server.IntegrationTests
Assert.Equal("Contoso", (string) response[Claims.ClientId]);
}
- [Fact]
- public async Task HandleIntrospectionRequest_NonBasicAuthorizationCodeClaimsAreNotReturned()
- {
- // Arrange
- await using var server = await CreateServerAsync(options =>
- {
- options.EnableDegradedMode();
-
- options.AddEventHandler(builder =>
- {
- builder.UseInlineHandler(context =>
- {
- Assert.Equal("2YotnFZFEjr1zCsicMWpAA", context.Token);
-
- context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.AuthorizationCode)
- .SetPresenters("Fabrikam")
- .SetClaim(Claims.Username, "Bob")
- .SetClaim("custom_claim", "secret_value");
-
- return default;
- });
-
- builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
- });
- });
-
- await using var client = await server.CreateClientAsync();
-
- // Act
- var response = await client.PostAsync("/connect/introspect", new OpenIddictRequest
- {
- ClientId = "Fabrikam",
- ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw",
- Token = "2YotnFZFEjr1zCsicMWpAA",
- TokenTypeHint = TokenTypeHints.AuthorizationCode
- });
-
- // Assert
- Assert.Null(response["custom_claim"]);
- Assert.Null(response[Claims.Username]);
- }
-
[Fact]
public async Task HandleIntrospectionRequest_NonBasicRefreshTokenClaimsAreNotReturned()
{
@@ -993,63 +869,6 @@ namespace OpenIddict.Server.IntegrationTests
Assert.Equal("openid profile", (string) response[Claims.Scope]);
}
- [Fact]
- public async Task HandleIntrospectionRequest_NonBasicIdentityClaimsAreReturnedToTrustedAudiences()
- {
- // Arrange
- var application = new OpenIddictApplication();
-
- var manager = CreateApplicationManager(mock =>
- {
- mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny()))
- .ReturnsAsync(application);
-
- mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Confidential, It.IsAny()))
- .ReturnsAsync(true);
-
- mock.Setup(manager => manager.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny()))
- .ReturnsAsync(true);
- });
-
- await using var server = await CreateServerAsync(options =>
- {
- options.AddEventHandler(builder =>
- {
- builder.UseInlineHandler(context =>
- {
- Assert.Equal("2YotnFZFEjr1zCsicMWpAA", context.Token);
-
- context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.IdToken)
- .SetAudiences("Fabrikam")
- .SetClaim(Claims.Username, "Bob")
- .SetClaim("custom_claim", "secret_value");
-
- return default;
- });
-
- builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
- });
-
- options.Services.AddSingleton(manager);
- });
-
- await using var client = await server.CreateClientAsync();
-
- // Act
- var response = await client.PostAsync("/connect/introspect", new OpenIddictRequest
- {
- ClientId = "Fabrikam",
- ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw",
- Token = "2YotnFZFEjr1zCsicMWpAA",
- TokenTypeHint = TokenTypeHints.IdToken
- });
-
- // Assert
- Assert.Equal("secret_value", (string) response["custom_claim"]);
- Assert.Equal("Bob", (string) response[Claims.Username]);
- }
-
[Fact]
public async Task HandleIntrospectionRequest_ClaimValueTypesAreHonored()
{
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Revocation.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Revocation.cs
index 02ef0258..62d91eb9 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Revocation.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Revocation.cs
@@ -153,8 +153,13 @@ namespace OpenIddict.Server.IntegrationTests
Assert.Equal(SR.FormatID3029(Parameters.Token), response.ErrorDescription);
}
- [Fact]
- public async Task ValidateRevocationRequest_IdentityTokenCausesAnUnsupportedTokenTypeError()
+ [Theory]
+ [InlineData(TokenTypeHints.AuthorizationCode)]
+ [InlineData(TokenTypeHints.DeviceCode)]
+ [InlineData(TokenTypeHints.IdToken)]
+ [InlineData(TokenTypeHints.UserCode)]
+ [InlineData("custom_token")]
+ public async Task ValidateRevocationRequest_UnsupportedTokenTypeCausesAnError(string type)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@@ -165,11 +170,10 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
- Assert.Equal("2YotnFZFEjr1zCsicMWpAA", context.Token);
+ Assert.Equal("5HtRgAtc02", context.Token);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.IdToken)
- .SetAudiences("AdventureWorks");
+ .SetTokenType(type);
return default;
});
@@ -186,8 +190,7 @@ namespace OpenIddict.Server.IntegrationTests
var response = await client.PostAsync("/connect/revoke", new OpenIddictRequest
{
ClientId = "Fabrikam",
- Token = "2YotnFZFEjr1zCsicMWpAA",
- TokenTypeHint = TokenTypeHints.IdToken
+ Token = "5HtRgAtc02"
});
// Assert
@@ -195,48 +198,6 @@ namespace OpenIddict.Server.IntegrationTests
Assert.Equal(SR.GetResourceString(SR.ID3079), response.ErrorDescription);
}
- [Fact]
- public async Task ValidateRevocationRequest_AuthorizationCodeCausesAnErrorWhenCallerIsNotAValidPresenter()
- {
- // Arrange
- await using var server = await CreateServerAsync(options =>
- {
- options.EnableDegradedMode();
-
- options.AddEventHandler(builder =>
- {
- builder.UseInlineHandler(context =>
- {
- Assert.Equal("SlAV32hkKG", context.Token);
-
- context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
- .SetTokenType(TokenTypeHints.AuthorizationCode)
- .SetPresenters("Contoso");
-
- return default;
- });
-
- builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
- });
-
- options.RemoveEventHandler(NormalizeErrorResponse.Descriptor);
- });
-
- await using var client = await server.CreateClientAsync();
-
- // Act
- var response = await client.PostAsync("/connect/revoke", new OpenIddictRequest
- {
- ClientId = "Fabrikam",
- Token = "SlAV32hkKG",
- TokenTypeHint = TokenTypeHints.AuthorizationCode
- });
-
- // Assert
- Assert.Equal(Errors.InvalidToken, response.Error);
- Assert.Equal(SR.GetResourceString(SR.ID3080), response.ErrorDescription);
- }
-
[Fact]
public async Task ValidateRevocationRequest_AccessTokenCausesAnErrorWhenCallerIsNotAValidAudienceOrPresenter()
{