/* * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) * See https://github.com/openiddict/openiddict-core for more information concerning * the license and the contributors participating to this project. */ using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using AspNet.Security.OpenIdConnect.Client; using AspNet.Security.OpenIdConnect.Extensions; using AspNet.Security.OpenIdConnect.Primitives; using AspNet.Security.OpenIdConnect.Server; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Authentication; using Microsoft.Extensions.DependencyInjection; using Moq; using OpenIddict.Core; using OpenIddict.Models; using Xunit; namespace OpenIddict.Tests { public partial class OpenIddictProviderTests { [Fact] public async Task ExtractIntrospectionRequest_GetRequestsAreRejected() { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.GetAsync(IntrospectionEndpoint, new OpenIdConnectRequest { Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Equal(OpenIdConnectConstants.Errors.InvalidRequest, response.Error); Assert.Equal("The specified HTTP method is not valid.", response.ErrorDescription); } [Theory] [InlineData("client_id", "")] [InlineData("", "client_secret")] public async Task ValidateIntrospectionRequest_ClientCredentialsRequestIsRejectedWhenCredentialsAreMissing(string identifier, string secret) { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = identifier, ClientSecret = secret, Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Equal(OpenIdConnectConstants.Errors.InvalidRequest, response.Error); Assert.Equal("The mandatory 'client_id' and/or 'client_secret' parameters are missing.", response.ErrorDescription); } [Fact] public async Task ValidateIntrospectionRequest_RequestIsRejectedWhenClientCannotBeFound() { // Arrange var manager = CreateApplicationManager(instance => { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(value: null); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Equal(OpenIdConnectConstants.Errors.InvalidClient, response.Error); Assert.Equal("The specified 'client_id' parameter is invalid.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); } [Fact] public async Task ValidateIntrospectionRequest_RequestsSentByPublicClientsAreRejected() { // Arrange var application = new OpenIddictApplication(); var manager = CreateApplicationManager(instance => { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Public); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Equal(OpenIdConnectConstants.Errors.InvalidClient, response.Error); Assert.Equal("This client application is not allowed to use the introspection endpoint.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } [Fact] public async Task ValidateIntrospectionRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() { // Arrange var application = new OpenIddictApplication(); var manager = CreateApplicationManager(instance => { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(false); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Equal(OpenIdConnectConstants.Errors.InvalidClient, response.Error); Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny()), Times.Once()); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenClientIsNotAValidAudience() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetAudiences("Contoso"); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AccessToken); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Configure(options => options.AccessTokenFormat = format.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); } [Fact] public async Task HandleIntrospectionRequest_AuthorizationCodeRevocationIsIgnoredWhenTokenRevocationIsDisabled() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AuthorizationCode); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Configure(options => options.AuthorizationCodeFormat = format.Object); builder.Configure(options => options.RevocationEndpointPath = PathString.Empty); builder.DisableTokenRevocation(); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.True((bool) response[OpenIdConnectConstants.Claims.Active]); } [Fact] public async Task HandleIntrospectionRequest_RefreshTokenRevocationIsIgnoredWhenTokenRevocationIsDisabled() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AuthorizationCode); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Configure(options => options.AuthorizationCodeFormat = format.Object); builder.Configure(options => options.RevocationEndpointPath = PathString.Empty); builder.DisableTokenRevocation(); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.True((bool) response[OpenIdConnectConstants.Claims.Active]); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenAccessTokenIsUnknown() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var manager = CreateTokenManager(instance => { instance.Setup(mock => mock.FindByHashAsync("coYFMTIt6jDp2O41qaUfV+XGhPsils3Z3YfmUvudrVw=", It.IsAny())) .ReturnsAsync(value: null); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Services.AddSingleton(manager); builder.UseReferenceTokens(); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "QaTk2f6UPe9trKismGBJr0OIs0KqpvNrqRsJqGuJAAI" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); Mock.Get(manager).Verify(mock => mock.FindByHashAsync("coYFMTIt6jDp2O41qaUfV+XGhPsils3Z3YfmUvudrVw=", It.IsAny()), Times.Exactly(3)); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenAccessTokenIsInvalid() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AccessToken); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var token = new OpenIddictToken(); var manager = CreateTokenManager(instance => { instance.Setup(mock => mock.FindByHashAsync("coYFMTIt6jDp2O41qaUfV+XGhPsils3Z3YfmUvudrVw=", It.IsAny())) .ReturnsAsync(token); instance.Setup(mock => mock.GetIdAsync(token, It.IsAny())) .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); instance.Setup(mock => mock.GetCiphertextAsync(token, It.IsAny())) .ReturnsAsync("2YotnFZFEjr1zCsicMWpAA"); instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(token); instance.Setup(mock => mock.IsValidAsync(token, It.IsAny())) .ReturnsAsync(false); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Services.AddSingleton(manager); builder.Configure(options => options.AccessTokenFormat = format.Object); builder.UseReferenceTokens(); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "QaTk2f6UPe9trKismGBJr0OIs0KqpvNrqRsJqGuJAAI" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); Mock.Get(manager).Verify(mock => mock.FindByHashAsync("coYFMTIt6jDp2O41qaUfV+XGhPsils3Z3YfmUvudrVw=", It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.IsValidAsync(token, It.IsAny()), Times.Once()); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenAuthorizationCodeIsUnknown() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AuthorizationCode); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var manager = CreateTokenManager(instance => { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(value: null); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Services.AddSingleton(manager); builder.Configure(options => options.AuthorizationCodeFormat = format.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()), Times.Once()); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenAuthorizationCodeIsInvalid() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AuthorizationCode); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var token = new OpenIddictToken(); var manager = CreateTokenManager(instance => { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(token); instance.Setup(mock => mock.IsValidAsync(token, It.IsAny())) .ReturnsAsync(false); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Services.AddSingleton(manager); builder.Configure(options => options.AuthorizationCodeFormat = format.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.IsValidAsync(token, It.IsAny()), Times.Once()); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenRefreshTokenIsUnknown() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var manager = CreateTokenManager(instance => { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(value: null); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.GetIdAsync(application, It.IsAny())) .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Services.AddSingleton(manager); builder.Configure(options => options.RefreshTokenFormat = format.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()), Times.Once()); } [Fact] public async Task HandleIntrospectionRequest_RequestIsRejectedWhenRefreshTokenIsInvalid() { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); var format = new Mock>(); format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); var token = new OpenIddictToken(); var manager = CreateTokenManager(instance => { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(token); instance.Setup(mock => mock.IsValidAsync(token, It.IsAny())) .ReturnsAsync(false); }); var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(CreateApplicationManager(instance => { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny())) .ReturnsAsync(true); })); builder.Services.AddSingleton(manager); builder.Configure(options => options.RefreshTokenFormat = format.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" }); // Assert Assert.Single(response.GetParameters()); Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.IsValidAsync(token, It.IsAny()), Times.Once()); } } }