From 371afd23030ddb088ed3617c53630963c03b9c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 6 May 2021 17:31:19 +0200 Subject: [PATCH 1/4] Update the ASP.NET Core/OWIN server/validation hosts to populate AuthenticationProperties.IssuedUtc/ExpiresUtc --- .../OpenIddictServerAspNetCoreHandler.cs | 7 +- .../OpenIddictServerOwinHandler.cs | 6 +- .../OpenIddictValidationAspNetCoreHandler.cs | 7 +- .../OpenIddictValidationOwinHandler.cs | 6 +- ...nIddictServerAspNetCoreIntegrationTests.cs | 124 +++++++++++++++++- .../OpenIddictServerOwinIntegrationTests.cs | 124 +++++++++++++++++- 6 files changed, 262 insertions(+), 12 deletions(-) diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs index 2d214c47..536c2fbc 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs @@ -161,7 +161,12 @@ namespace OpenIddict.Server.AspNetCore // Store the token to allow any OWIN/Katana component (e.g a controller) // to retrieve it (e.g to make an API request to another application). - var properties = new AuthenticationProperties(); + var properties = new AuthenticationProperties + { + ExpiresUtc = context.Principal.GetExpirationDate(), + IssuedUtc = context.Principal.GetCreationDate() + }; + properties.StoreTokens(new[] { new AuthenticationToken diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs index ca5bc475..e015ab32 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs @@ -176,7 +176,11 @@ namespace OpenIddict.Server.Owin var properties = new AuthenticationProperties(new Dictionary { [context.Principal.GetTokenType()!] = context.Token - }); + }) + { + ExpiresUtc = context.Principal.GetExpirationDate(), + IssuedUtc = context.Principal.GetCreationDate() + }; return new AuthenticationTicket((ClaimsIdentity) context.Principal.Identity, properties); } diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs index 1835ecd8..262a6268 100644 --- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs +++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs @@ -159,7 +159,12 @@ namespace OpenIddict.Validation.AspNetCore // Store the token to allow any ASP.NET Core component (e.g a controller) // to retrieve it (e.g to make an API request to another application). - var properties = new AuthenticationProperties(); + var properties = new AuthenticationProperties + { + ExpiresUtc = context.Principal.GetExpirationDate(), + IssuedUtc = context.Principal.GetCreationDate() + }; + properties.StoreTokens(new[] { new AuthenticationToken diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs index 67c3885b..497cedff 100644 --- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs +++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs @@ -173,7 +173,11 @@ namespace OpenIddict.Validation.Owin var properties = new AuthenticationProperties(new Dictionary { [context.Principal.GetTokenType()!] = context.Token - }); + }) + { + ExpiresUtc = context.Principal.GetExpirationDate(), + IssuedUtc = context.Principal.GetCreationDate() + }; return new AuthenticationTicket((ClaimsIdentity) context.Principal.Identity, properties); } diff --git a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs index e4c44603..1b2d9133 100644 --- a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs +++ b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs @@ -26,6 +26,7 @@ using Xunit.Abstractions; using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers; using static OpenIddict.Server.OpenIddictServerEvents; +using static OpenIddict.Server.OpenIddictServerHandlers; using SR = OpenIddict.Abstractions.OpenIddictResources; namespace OpenIddict.Server.AspNetCore.IntegrationTests @@ -37,6 +38,107 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests { } + [Fact] + public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc() + { + // Arrange + await using var server = await CreateServerAsync(options => + { + options.EnableDegradedMode(); + options.SetUserinfoEndpointUris("/authenticate/properties"); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + { + builder.UseInlineHandler(context => + { + Assert.Equal("access_token", context.Token); + Assert.Equal(TokenTypeHints.AccessToken, context.TokenType); + + context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) + .SetTokenType(TokenTypeHints.AccessToken) + .SetClaim(Claims.Subject, "Bob le Magnifique") + .SetCreationDate(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero)); + + return default; + }); + + builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500); + }); + }); + + await using var client = await server.CreateClientAsync(); + + // Act + var response = await client.GetAsync("/authenticate/properties", new OpenIddictRequest + { + AccessToken = "access_token" + }); + + // Assert + var properties = new AuthenticationProperties(response.GetParameters() + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + + Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc); + } + + [Fact] + public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc() + { + // Arrange + await using var server = await CreateServerAsync(options => + { + options.EnableDegradedMode(); + options.SetUserinfoEndpointUris("/authenticate/properties"); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + { + builder.UseInlineHandler(context => + { + Assert.Equal("access_token", context.Token); + Assert.Equal(TokenTypeHints.AccessToken, context.TokenType); + + context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) + .SetTokenType(TokenTypeHints.AccessToken) + .SetExpirationDate(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero)); + + return default; + }); + + builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500); + }); + }); + + await using var client = await server.CreateClientAsync(); + + // Act + var response = await client.GetAsync("/authenticate/properties", new OpenIddictRequest + { + AccessToken = "access_token" + }); + + // Assert + var properties = new AuthenticationProperties(response.GetParameters() + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + + Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc); + } + [Fact] public async Task ProcessChallenge_ReturnsParametersFromAuthenticationProperties() { @@ -601,11 +703,25 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests return; } + var claims = result.Principal.Claims.GroupBy(claim => claim.Type) + .Select(group => new KeyValuePair( + group.Key, group.Select(claim => claim.Value).ToArray())); + + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(claims))); + return; + } + + else if (context.Request.Path == "/authenticate/properties") + { + var result = await context.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); + if (result?.Properties is null) + { + return; + } + context.Response.ContentType = "application/json"; - await context.Response.WriteAsync(JsonSerializer.Serialize( - new OpenIddictResponse(result.Principal.Claims.GroupBy(claim => claim.Type) - .Select(group => new KeyValuePair( - group.Key, group.Select(claim => claim.Value).ToArray()))))); + await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(result.Properties.Items))); return; } diff --git a/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs b/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs index ad6b31e5..066d179e 100644 --- a/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs +++ b/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs @@ -23,6 +23,7 @@ using Xunit; using Xunit.Abstractions; using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Server.OpenIddictServerEvents; +using static OpenIddict.Server.OpenIddictServerHandlers; using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlers; using SR = OpenIddict.Abstractions.OpenIddictResources; @@ -35,6 +36,107 @@ namespace OpenIddict.Server.Owin.IntegrationTests { } + [Fact] + public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc() + { + // Arrange + await using var server = await CreateServerAsync(options => + { + options.EnableDegradedMode(); + options.SetUserinfoEndpointUris("/authenticate/properties"); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + { + builder.UseInlineHandler(context => + { + Assert.Equal("access_token", context.Token); + Assert.Equal(TokenTypeHints.AccessToken, context.TokenType); + + context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) + .SetTokenType(TokenTypeHints.AccessToken) + .SetClaim(Claims.Subject, "Bob le Magnifique") + .SetCreationDate(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero)); + + return default; + }); + + builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500); + }); + }); + + await using var client = await server.CreateClientAsync(); + + // Act + var response = await client.GetAsync("/authenticate/properties", new OpenIddictRequest + { + AccessToken = "access_token" + }); + + // Assert + var properties = new AuthenticationProperties(response.GetParameters() + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + + Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc); + } + + [Fact] + public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc() + { + // Arrange + await using var server = await CreateServerAsync(options => + { + options.EnableDegradedMode(); + options.SetUserinfoEndpointUris("/authenticate/properties"); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + { + builder.UseInlineHandler(context => + { + Assert.Equal("access_token", context.Token); + Assert.Equal(TokenTypeHints.AccessToken, context.TokenType); + + context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) + .SetTokenType(TokenTypeHints.AccessToken) + .SetExpirationDate(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero)); + + return default; + }); + + builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500); + }); + }); + + await using var client = await server.CreateClientAsync(); + + // Act + var response = await client.GetAsync("/authenticate/properties", new OpenIddictRequest + { + AccessToken = "access_token" + }); + + // Assert + var properties = new AuthenticationProperties(response.GetParameters() + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + + Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc); + } + [Fact] public async Task ProcessChallenge_ReturnsErrorFromAuthenticationProperties() { @@ -423,11 +525,25 @@ namespace OpenIddict.Server.Owin.IntegrationTests return; } + var claims = result.Identity.Claims.GroupBy(claim => claim.Type) + .Select(group => new KeyValuePair( + group.Key, group.Select(claim => claim.Value).ToArray())); + + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(claims))); + return; + } + + else if (context.Request.Path == new PathString("/authenticate/properties")) + { + var result = await context.Authentication.AuthenticateAsync(OpenIddictServerOwinDefaults.AuthenticationType); + if (result?.Properties is null) + { + return; + } + context.Response.ContentType = "application/json"; - await context.Response.WriteAsync(JsonSerializer.Serialize( - new OpenIddictResponse(result.Identity.Claims.GroupBy(claim => claim.Type) - .Select(group => new KeyValuePair( - group.Key, group.Select(claim => claim.Value).ToArray()))!))); + await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(result.Properties.Dictionary))); return; } From f4558760027201ddcd1cc768f36538dadf60075d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 6 May 2021 18:11:43 +0200 Subject: [PATCH 2/4] Update the OpenIddictAuthorizationManager.CreateAsync() overload that doesn't take a descriptor to automatically populate the creation date --- src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index 2ee0b741..b5b42990 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -223,6 +223,7 @@ namespace OpenIddict.Core var descriptor = new OpenIddictAuthorizationDescriptor { ApplicationId = client, + CreationDate = DateTimeOffset.UtcNow, Principal = principal, Status = Statuses.Valid, Subject = subject, From 488c068f8b43771dfa7f99514d846b0db811e7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 7 May 2021 15:27:54 +0200 Subject: [PATCH 3/4] Fix the ASP.NET Core/OWIN InferEndpointType handler to correctly compare absolute URLs --- ...ServerAspNetCoreHandlers.Authentication.cs | 2 +- ...nIddictServerAspNetCoreHandlers.Session.cs | 2 +- .../OpenIddictServerAspNetCoreHandlers.cs | 12 +- ...IddictServerOwinHandlers.Authentication.cs | 2 +- .../OpenIddictServerOwinHandlers.Session.cs | 2 +- .../OpenIddictServerOwinHandlers.cs | 12 +- .../OpenIddictValidationAspNetCoreHandlers.cs | 2 +- .../OpenIddictValidationOwinHandlers.cs | 2 +- ...nIddictServerAspNetCoreIntegrationTests.cs | 303 +++++++++++++++-- .../OpenIddictServerOwinIntegrationTests.cs | 307 ++++++++++++++++-- 10 files changed, 588 insertions(+), 58 deletions(-) diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs index 994589f8..5648551c 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs @@ -249,7 +249,7 @@ namespace OpenIddict.Server.AspNetCore // Create a new GET authorization request containing only the request_id parameter. var address = QueryHelpers.AddQueryString( - uri: request.Scheme + "://" + request.Host + request.PathBase + request.Path, + uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path, name: Parameters.RequestId, value: context.Request.RequestId); diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs index 98f340e8..fb444a82 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs @@ -247,7 +247,7 @@ namespace OpenIddict.Server.AspNetCore // Create a new GET logout request containing only the request_id parameter. var address = QueryHelpers.AddQueryString( - uri: request.Scheme + "://" + request.Host + request.PathBase + request.Path, + uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path, name: Parameters.RequestId, value: context.Request.RequestId); diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs index 9e40072b..4e6f9857 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs @@ -127,13 +127,17 @@ namespace OpenIddict.Server.AspNetCore var address = addresses[index]; if (address.IsAbsoluteUri) { - if (!string.Equals(address.Scheme, request.Scheme, StringComparison.OrdinalIgnoreCase)) + // If the request host is not available (e.g because HTTP/1.0 was used), ignore absolute URLs. + if (!request.Host.HasValue) { continue; } - var host = HostString.FromUriComponent(address); - if (host != request.Host) + // Create a Uri instance using the request scheme and raw host and compare the two base addresses. + if (!Uri.TryCreate(request.Scheme + Uri.SchemeDelimiter + request.Host, UriKind.Absolute, out Uri? uri) || + !uri.IsWellFormedOriginalString() || uri.Port != address.Port || + !string.Equals(uri.Scheme, address.Scheme, StringComparison.OrdinalIgnoreCase) || + !string.Equals(uri.Host, address.Host, StringComparison.OrdinalIgnoreCase)) { continue; } @@ -219,7 +223,7 @@ namespace OpenIddict.Server.AspNetCore return default; } - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || + if (!Uri.TryCreate(request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || !issuer.IsWellFormedOriginalString()) { context.Reject( diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs index b2987c35..6c786cad 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs @@ -243,7 +243,7 @@ namespace OpenIddict.Server.Owin // Create a new GET authorization request containing only the request_id parameter. var address = WebUtilities.AddQueryString( - uri: request.Scheme + "://" + request.Host + request.PathBase + request.Path, + uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path, name: Parameters.RequestId, value: context.Request.RequestId); diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs index 3b346758..dc41bfce 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs @@ -241,7 +241,7 @@ namespace OpenIddict.Server.Owin // Create a new GET logout request containing only the request_id parameter. var address = WebUtilities.AddQueryString( - uri: request.Scheme + "://" + request.Host + request.PathBase + request.Path, + uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path, name: Parameters.RequestId, value: context.Request.RequestId); diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs index 54f07242..14aa5b88 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs @@ -116,13 +116,17 @@ namespace OpenIddict.Server.Owin var address = addresses[index]; if (address.IsAbsoluteUri) { - if (!string.Equals(address.Scheme, request.Scheme, StringComparison.OrdinalIgnoreCase)) + // If the request host is not available (e.g because HTTP/1.0 was used), ignore absolute URLs. + if (string.IsNullOrEmpty(request.Host.Value)) { continue; } - var host = HostString.FromUriComponent(address); - if (host != request.Host) + // Create a Uri instance using the request scheme and raw host and compare the two base addresses. + if (!Uri.TryCreate(request.Scheme + Uri.SchemeDelimiter + request.Host, UriKind.Absolute, out Uri? uri) || + !uri.IsWellFormedOriginalString() || uri.Port != address.Port || + !string.Equals(uri.Scheme, address.Scheme, StringComparison.OrdinalIgnoreCase) || + !string.Equals(uri.Host, address.Host, StringComparison.OrdinalIgnoreCase)) { continue; } @@ -208,7 +212,7 @@ namespace OpenIddict.Server.Owin return default; } - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || + if (!Uri.TryCreate(request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || !issuer.IsWellFormedOriginalString()) { context.Reject( diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs index 249161a2..b47c1c45 100644 --- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs +++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs @@ -115,7 +115,7 @@ namespace OpenIddict.Validation.AspNetCore return default; } - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || + if (!Uri.TryCreate(request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || !issuer.IsWellFormedOriginalString()) { context.Reject( diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs index 02c3f70f..3c9760ee 100644 --- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs +++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs @@ -113,7 +113,7 @@ namespace OpenIddict.Validation.Owin return default; } - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || + if (!Uri.TryCreate(request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) || !issuer.IsWellFormedOriginalString()) { context.Reject( diff --git a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs index 1b2d9133..500bf9d0 100644 --- a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs +++ b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs @@ -228,6 +228,30 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests [InlineData("/CONNECT/AUTHORIZE/SUBPATH", OpenIddictServerEndpointType.Unknown)] [InlineData("/connect/authorize/subpath/", OpenIddictServerEndpointType.Unknown)] [InlineData("/CONNECT/AUTHORIZE/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.well-known/openid-configuration/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/openid-configuration/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.well-known/jwks/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/JWKS/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/jwks/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/JWKS/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/connect/device", OpenIddictServerEndpointType.Device)] + [InlineData("/CONNECT/DEVICE", OpenIddictServerEndpointType.Device)] + [InlineData("/connect/device/", OpenIddictServerEndpointType.Device)] + [InlineData("/CONNECT/DEVICE/", OpenIddictServerEndpointType.Device)] + [InlineData("/connect/device/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/DEVICE/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/connect/device/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/DEVICE/SUBPATH/", OpenIddictServerEndpointType.Unknown)] [InlineData("/connect/introspect", OpenIddictServerEndpointType.Introspection)] [InlineData("/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Introspection)] [InlineData("/connect/introspect/", OpenIddictServerEndpointType.Introspection)] @@ -268,23 +292,15 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests [InlineData("/CONNECT/USERINFO/SUBPATH", OpenIddictServerEndpointType.Unknown)] [InlineData("/connect/userinfo/subpath/", OpenIddictServerEndpointType.Unknown)] [InlineData("/CONNECT/USERINFO/SUBPATH/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.well-known/openid-configuration/subpath", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/openid-configuration/subpath/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.well-known/jwks/subpath", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/JWKS/SUBPATH", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/jwks/subpath/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/JWKS/SUBPATH/", OpenIddictServerEndpointType.Unknown)] - public async Task ProcessRequest_MatchesCorrespondingEndpoint(string path, OpenIddictServerEndpointType type) + [InlineData("/connect/verification", OpenIddictServerEndpointType.Verification)] + [InlineData("/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Verification)] + [InlineData("/connect/verification/", OpenIddictServerEndpointType.Verification)] + [InlineData("/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Verification)] + [InlineData("/connect/verification/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/VERIFICATION/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/connect/verification/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/VERIFICATION/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + public async Task ProcessRequest_MatchesCorrespondingRelativeEndpoint(string path, OpenIddictServerEndpointType type) { // Arrange await using var server = await CreateServerAsync(options => @@ -294,7 +310,236 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests options.AddEventHandler(builder => builder.UseInlineHandler(context => { - context.SignOut(); + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + // Assert + Assert.Equal(type, context.EndpointType); + + return default; + })); + }); + + await using var client = await server.CreateClientAsync(); + + // Act + await client.PostAsync(path, new OpenIddictRequest()); + } + + [Theory] + [InlineData("https://localhost/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:443/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST/CONNECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST/CONNECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:443/connect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:443/connect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/authorize", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://localhost/connect/authorize/", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://localhost:443/connect/authorize", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://localhost:443/connect/authorize/", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://fabrikam.com/connect/authorize", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/authorize/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/authorize", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/authorize/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://localhost/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://localhost:443/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://localhost:443/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://fabrikam.com/.well-known/openid-configuration", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/.well-known/openid-configuration/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/openid-configuration", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/openid-configuration/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://localhost/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://localhost:443/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://localhost:443/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://fabrikam.com/.well-known/jwks", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/.well-known/jwks/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/jwks", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/jwks/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/device", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST/CONNECT/DEVICE", OpenIddictServerEndpointType.Device)] + [InlineData("https://localhost/connect/device/", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST/CONNECT/DEVICE/", OpenIddictServerEndpointType.Device)] + [InlineData("https://localhost:443/connect/device", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/DEVICE", OpenIddictServerEndpointType.Device)] + [InlineData("https://localhost:443/connect/device/", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/DEVICE/", OpenIddictServerEndpointType.Device)] + [InlineData("https://fabrikam.com/connect/device", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/DEVICE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/device/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/DEVICE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/device", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/DEVICE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/device/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/DEVICE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/introspect", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://localhost/connect/introspect/", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://localhost:443/connect/introspect", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://localhost:443/connect/introspect/", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://fabrikam.com/connect/introspect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/introspect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/introspect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/introspect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/logout", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST/CONNECT/LOGOUT", OpenIddictServerEndpointType.Logout)] + [InlineData("https://localhost/connect/logout/", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Logout)] + [InlineData("https://localhost:443/connect/logout", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/LOGOUT", OpenIddictServerEndpointType.Logout)] + [InlineData("https://localhost:443/connect/logout/", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Logout)] + [InlineData("https://fabrikam.com/connect/logout", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/LOGOUT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/logout/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/logout", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/LOGOUT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/logout/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/revoke", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST/CONNECT/REVOKE", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://localhost/connect/revoke/", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST/CONNECT/REVOKE/", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://localhost:443/connect/revoke", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/REVOKE", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://localhost:443/connect/revoke/", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/REVOKE/", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://fabrikam.com/connect/revoke", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/REVOKE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/revoke/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/REVOKE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/revoke", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/REVOKE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/revoke/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/REVOKE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/token", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST/CONNECT/TOKEN", OpenIddictServerEndpointType.Token)] + [InlineData("https://localhost/connect/token/", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST/CONNECT/TOKEN/", OpenIddictServerEndpointType.Token)] + [InlineData("https://localhost:443/connect/token", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/TOKEN", OpenIddictServerEndpointType.Token)] + [InlineData("https://localhost:443/connect/token/", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/TOKEN/", OpenIddictServerEndpointType.Token)] + [InlineData("https://fabrikam.com/connect/token", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/TOKEN", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/token/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/TOKEN/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/token", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/TOKEN", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/token/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/TOKEN/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/userinfo", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST/CONNECT/USERINFO", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://localhost/connect/userinfo/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST/CONNECT/USERINFO/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://localhost:443/connect/userinfo", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/USERINFO", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://localhost:443/connect/userinfo/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/USERINFO/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://fabrikam.com/connect/userinfo", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/USERINFO", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/userinfo/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/USERINFO/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/userinfo", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/USERINFO", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/userinfo/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/USERINFO/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/verification", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Verification)] + [InlineData("https://localhost/connect/verification/", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Verification)] + [InlineData("https://localhost:443/connect/verification", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Verification)] + [InlineData("https://localhost:443/connect/verification/", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Verification)] + [InlineData("https://fabrikam.com/connect/verification", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/verification/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/verification", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/verification/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Unknown)] + public async Task ProcessRequest_MatchesCorrespondingAbsoluteEndpoint(string path, OpenIddictServerEndpointType type) + { + // Arrange + await using var server = await CreateServerAsync(options => + { + options.EnableDegradedMode(); + + options.SetAuthorizationEndpointUris("https://localhost/connect/authorize") + .SetConfigurationEndpointUris("https://localhost/.well-known/openid-configuration") + .SetCryptographyEndpointUris("https://localhost/.well-known/jwks") + .SetDeviceEndpointUris("https://localhost/connect/device") + .SetIntrospectionEndpointUris("https://localhost/connect/introspect") + .SetLogoutEndpointUris("https://localhost/connect/logout") + .SetRevocationEndpointUris("https://localhost/connect/revoke") + .SetTokenEndpointUris("https://localhost/connect/token") + .SetUserinfoEndpointUris("https://localhost/connect/userinfo") + .SetVerificationEndpointUris("https://localhost/connect/verification"); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); return default; })); @@ -317,14 +562,16 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests [Theory] [InlineData("/custom/connect/authorize", OpenIddictServerEndpointType.Authorization)] + [InlineData("/custom/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("/custom/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/custom/connect/device", OpenIddictServerEndpointType.Device)] [InlineData("/custom/connect/custom", OpenIddictServerEndpointType.Unknown)] [InlineData("/custom/connect/introspect", OpenIddictServerEndpointType.Introspection)] [InlineData("/custom/connect/logout", OpenIddictServerEndpointType.Logout)] [InlineData("/custom/connect/revoke", OpenIddictServerEndpointType.Revocation)] [InlineData("/custom/connect/token", OpenIddictServerEndpointType.Token)] [InlineData("/custom/connect/userinfo", OpenIddictServerEndpointType.Userinfo)] - [InlineData("/custom/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] - [InlineData("/custom/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/custom/connect/verification", OpenIddictServerEndpointType.Verification)] public async Task ProcessRequest_AllowsOverridingEndpoint(string address, OpenIddictServerEndpointType type) { // Arrange @@ -335,7 +582,15 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests options.AddEventHandler(builder => builder.UseInlineHandler(context => { - context.SignOut(); + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); return default; })); @@ -367,11 +622,13 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests [InlineData("/.well-known/openid-configuration")] [InlineData("/.well-known/jwks")] [InlineData("/connect/authorize")] + [InlineData("/connect/device")] [InlineData("/connect/introspect")] [InlineData("/connect/logout")] [InlineData("/connect/revoke")] [InlineData("/connect/token")] [InlineData("/connect/userinfo")] + [InlineData("/connect/verification")] public async Task ProcessRequest_RejectsInsecureHttpRequests(string address) { // Arrange @@ -399,11 +656,13 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests [InlineData("/.well-known/jwks")] [InlineData("/custom")] [InlineData("/connect/authorize")] + [InlineData("/connect/device")] [InlineData("/connect/introspect")] [InlineData("/connect/logout")] [InlineData("/connect/revoke")] [InlineData("/connect/token")] [InlineData("/connect/userinfo")] + [InlineData("/connect/verification")] public async Task ProcessRequest_AllowsHandlingResponse(string address) { // Arrange @@ -439,11 +698,13 @@ namespace OpenIddict.Server.AspNetCore.IntegrationTests [InlineData("/.well-known/jwks")] [InlineData("/custom")] [InlineData("/connect/authorize")] + [InlineData("/connect/device")] [InlineData("/connect/introspect")] [InlineData("/connect/logout")] [InlineData("/connect/revoke")] [InlineData("/connect/token")] [InlineData("/connect/userinfo")] + [InlineData("/connect/verification")] public async Task ProcessRequest_AllowsSkippingHandler(string address) { // Arrange diff --git a/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs b/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs index 066d179e..6180680f 100644 --- a/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs +++ b/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs @@ -185,6 +185,30 @@ namespace OpenIddict.Server.Owin.IntegrationTests [InlineData("/CONNECT/AUTHORIZE/SUBPATH", OpenIddictServerEndpointType.Unknown)] [InlineData("/connect/authorize/subpath/", OpenIddictServerEndpointType.Unknown)] [InlineData("/CONNECT/AUTHORIZE/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] + [InlineData("/.well-known/openid-configuration/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/openid-configuration/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/.well-known/jwks/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/JWKS/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.well-known/jwks/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/.WELL-KNOWN/JWKS/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/connect/device", OpenIddictServerEndpointType.Device)] + [InlineData("/CONNECT/DEVICE", OpenIddictServerEndpointType.Device)] + [InlineData("/connect/device/", OpenIddictServerEndpointType.Device)] + [InlineData("/CONNECT/DEVICE/", OpenIddictServerEndpointType.Device)] + [InlineData("/connect/device/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/DEVICE/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/connect/device/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/DEVICE/SUBPATH/", OpenIddictServerEndpointType.Unknown)] [InlineData("/connect/introspect", OpenIddictServerEndpointType.Introspection)] [InlineData("/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Introspection)] [InlineData("/connect/introspect/", OpenIddictServerEndpointType.Introspection)] @@ -225,23 +249,15 @@ namespace OpenIddict.Server.Owin.IntegrationTests [InlineData("/CONNECT/USERINFO/SUBPATH", OpenIddictServerEndpointType.Unknown)] [InlineData("/connect/userinfo/subpath/", OpenIddictServerEndpointType.Unknown)] [InlineData("/CONNECT/USERINFO/SUBPATH/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] - [InlineData("/.well-known/openid-configuration/subpath", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/openid-configuration/subpath/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/OPENID-CONFIGURATION/SUBPATH/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] - [InlineData("/.well-known/jwks/subpath", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/JWKS/SUBPATH", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.well-known/jwks/subpath/", OpenIddictServerEndpointType.Unknown)] - [InlineData("/.WELL-KNOWN/JWKS/SUBPATH/", OpenIddictServerEndpointType.Unknown)] - public async Task ProcessRequest_MatchesCorrespondingEndpoint(string path, OpenIddictServerEndpointType type) + [InlineData("/connect/verification", OpenIddictServerEndpointType.Verification)] + [InlineData("/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Verification)] + [InlineData("/connect/verification/", OpenIddictServerEndpointType.Verification)] + [InlineData("/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Verification)] + [InlineData("/connect/verification/subpath", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/VERIFICATION/SUBPATH", OpenIddictServerEndpointType.Unknown)] + [InlineData("/connect/verification/subpath/", OpenIddictServerEndpointType.Unknown)] + [InlineData("/CONNECT/VERIFICATION/SUBPATH/", OpenIddictServerEndpointType.Unknown)] + public async Task ProcessRequest_MatchesCorrespondingRelativeEndpoint(string path, OpenIddictServerEndpointType type) { // Arrange await using var server = await CreateServerAsync(options => @@ -251,7 +267,236 @@ namespace OpenIddict.Server.Owin.IntegrationTests options.AddEventHandler(builder => builder.UseInlineHandler(context => { - context.SignOut(); + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + // Assert + Assert.Equal(type, context.EndpointType); + + return default; + })); + }); + + await using var client = await server.CreateClientAsync(); + + // Act + await client.PostAsync(path, new OpenIddictRequest()); + } + + [Theory] + [InlineData("https://localhost/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:443/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST/CONNECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST/CONNECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:443/connect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:443/connect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/authorize", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://localhost/connect/authorize/", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://localhost:443/connect/authorize", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://localhost:443/connect/authorize/", OpenIddictServerEndpointType.Authorization)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Authorization)] + [InlineData("https://fabrikam.com/connect/authorize", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/authorize/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/authorize", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/AUTHORIZE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/authorize/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/AUTHORIZE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://localhost/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://localhost:443/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://localhost:443/.well-known/openid-configuration/", OpenIddictServerEndpointType.Configuration)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Configuration)] + [InlineData("https://fabrikam.com/.well-known/openid-configuration", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/.well-known/openid-configuration/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/openid-configuration", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/OPENID-CONFIGURATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/openid-configuration/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/OPENID-CONFIGURATION/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://localhost/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://localhost:443/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://localhost:443/.well-known/jwks/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("HTTPS://LOCALHOST:443/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Cryptography)] + [InlineData("https://fabrikam.com/.well-known/jwks", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/.well-known/jwks/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/jwks", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/JWKS", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/.well-known/jwks/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/.WELL-KNOWN/JWKS/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/device", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST/CONNECT/DEVICE", OpenIddictServerEndpointType.Device)] + [InlineData("https://localhost/connect/device/", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST/CONNECT/DEVICE/", OpenIddictServerEndpointType.Device)] + [InlineData("https://localhost:443/connect/device", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/DEVICE", OpenIddictServerEndpointType.Device)] + [InlineData("https://localhost:443/connect/device/", OpenIddictServerEndpointType.Device)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/DEVICE/", OpenIddictServerEndpointType.Device)] + [InlineData("https://fabrikam.com/connect/device", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/DEVICE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/device/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/DEVICE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/device", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/DEVICE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/device/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/DEVICE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/introspect", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://localhost/connect/introspect/", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://localhost:443/connect/introspect", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://localhost:443/connect/introspect/", OpenIddictServerEndpointType.Introspection)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Introspection)] + [InlineData("https://fabrikam.com/connect/introspect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/introspect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/introspect", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/INTROSPECT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/introspect/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/INTROSPECT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/logout", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST/CONNECT/LOGOUT", OpenIddictServerEndpointType.Logout)] + [InlineData("https://localhost/connect/logout/", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Logout)] + [InlineData("https://localhost:443/connect/logout", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/LOGOUT", OpenIddictServerEndpointType.Logout)] + [InlineData("https://localhost:443/connect/logout/", OpenIddictServerEndpointType.Logout)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Logout)] + [InlineData("https://fabrikam.com/connect/logout", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/LOGOUT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/logout/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/logout", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/LOGOUT", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/logout/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/LOGOUT/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/revoke", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST/CONNECT/REVOKE", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://localhost/connect/revoke/", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST/CONNECT/REVOKE/", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://localhost:443/connect/revoke", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/REVOKE", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://localhost:443/connect/revoke/", OpenIddictServerEndpointType.Revocation)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/REVOKE/", OpenIddictServerEndpointType.Revocation)] + [InlineData("https://fabrikam.com/connect/revoke", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/REVOKE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/revoke/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/REVOKE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/revoke", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/REVOKE", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/revoke/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/REVOKE/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/token", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST/CONNECT/TOKEN", OpenIddictServerEndpointType.Token)] + [InlineData("https://localhost/connect/token/", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST/CONNECT/TOKEN/", OpenIddictServerEndpointType.Token)] + [InlineData("https://localhost:443/connect/token", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/TOKEN", OpenIddictServerEndpointType.Token)] + [InlineData("https://localhost:443/connect/token/", OpenIddictServerEndpointType.Token)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/TOKEN/", OpenIddictServerEndpointType.Token)] + [InlineData("https://fabrikam.com/connect/token", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/TOKEN", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/token/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/TOKEN/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/token", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/TOKEN", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/token/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/TOKEN/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/userinfo", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST/CONNECT/USERINFO", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://localhost/connect/userinfo/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST/CONNECT/USERINFO/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://localhost:443/connect/userinfo", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/USERINFO", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://localhost:443/connect/userinfo/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/USERINFO/", OpenIddictServerEndpointType.Userinfo)] + [InlineData("https://fabrikam.com/connect/userinfo", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/USERINFO", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/userinfo/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/USERINFO/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/userinfo", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/USERINFO", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/userinfo/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/USERINFO/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost/connect/verification", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Verification)] + [InlineData("https://localhost/connect/verification/", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Verification)] + [InlineData("https://localhost:443/connect/verification", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Verification)] + [InlineData("https://localhost:443/connect/verification/", OpenIddictServerEndpointType.Verification)] + [InlineData("HTTPS://LOCALHOST:443/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Verification)] + [InlineData("https://fabrikam.com/connect/verification", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://fabrikam.com/connect/verification/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://FABRIKAM.COM/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/verification", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/VERIFICATION", OpenIddictServerEndpointType.Unknown)] + [InlineData("https://localhost:8888/connect/verification/", OpenIddictServerEndpointType.Unknown)] + [InlineData("HTTPS://LOCALHOST:8888/CONNECT/VERIFICATION/", OpenIddictServerEndpointType.Unknown)] + public async Task ProcessRequest_MatchesCorrespondingAbsoluteEndpoint(string path, OpenIddictServerEndpointType type) + { + // Arrange + await using var server = await CreateServerAsync(options => + { + options.EnableDegradedMode(); + + options.SetAuthorizationEndpointUris("https://localhost/connect/authorize") + .SetConfigurationEndpointUris("https://localhost/.well-known/openid-configuration") + .SetCryptographyEndpointUris("https://localhost/.well-known/jwks") + .SetDeviceEndpointUris("https://localhost/connect/device") + .SetIntrospectionEndpointUris("https://localhost/connect/introspect") + .SetLogoutEndpointUris("https://localhost/connect/logout") + .SetRevocationEndpointUris("https://localhost/connect/revoke") + .SetTokenEndpointUris("https://localhost/connect/token") + .SetUserinfoEndpointUris("https://localhost/connect/userinfo") + .SetVerificationEndpointUris("https://localhost/connect/verification"); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); return default; })); @@ -274,14 +519,16 @@ namespace OpenIddict.Server.Owin.IntegrationTests [Theory] [InlineData("/custom/connect/authorize", OpenIddictServerEndpointType.Authorization)] + [InlineData("/custom/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] + [InlineData("/custom/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/custom/connect/device", OpenIddictServerEndpointType.Device)] [InlineData("/custom/connect/custom", OpenIddictServerEndpointType.Unknown)] [InlineData("/custom/connect/introspect", OpenIddictServerEndpointType.Introspection)] [InlineData("/custom/connect/logout", OpenIddictServerEndpointType.Logout)] [InlineData("/custom/connect/revoke", OpenIddictServerEndpointType.Revocation)] [InlineData("/custom/connect/token", OpenIddictServerEndpointType.Token)] [InlineData("/custom/connect/userinfo", OpenIddictServerEndpointType.Userinfo)] - [InlineData("/custom/.well-known/openid-configuration", OpenIddictServerEndpointType.Configuration)] - [InlineData("/custom/.well-known/jwks", OpenIddictServerEndpointType.Cryptography)] + [InlineData("/custom/connect/verification", OpenIddictServerEndpointType.Verification)] public async Task ProcessRequest_AllowsOverridingEndpoint(string address, OpenIddictServerEndpointType type) { // Arrange @@ -292,7 +539,15 @@ namespace OpenIddict.Server.Owin.IntegrationTests options.AddEventHandler(builder => builder.UseInlineHandler(context => { - context.SignOut(); + context.SkipRequest(); + + return default; + })); + + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + context.SkipRequest(); return default; })); @@ -324,11 +579,13 @@ namespace OpenIddict.Server.Owin.IntegrationTests [InlineData("/.well-known/openid-configuration")] [InlineData("/.well-known/jwks")] [InlineData("/connect/authorize")] + [InlineData("/connect/device")] [InlineData("/connect/introspect")] [InlineData("/connect/logout")] [InlineData("/connect/revoke")] [InlineData("/connect/token")] [InlineData("/connect/userinfo")] + [InlineData("/connect/verification")] public async Task ProcessRequest_RejectsInsecureHttpRequests(string address) { // Arrange @@ -356,11 +613,13 @@ namespace OpenIddict.Server.Owin.IntegrationTests [InlineData("/.well-known/jwks")] [InlineData("/custom")] [InlineData("/connect/authorize")] + [InlineData("/connect/device")] [InlineData("/connect/introspect")] [InlineData("/connect/logout")] [InlineData("/connect/revoke")] [InlineData("/connect/token")] [InlineData("/connect/userinfo")] + [InlineData("/connect/verification")] public async Task ProcessRequest_AllowsHandlingResponse(string address) { // Arrange @@ -388,7 +647,7 @@ namespace OpenIddict.Server.Owin.IntegrationTests var response = await client.PostAsync(address, new OpenIddictRequest()); // Assert - Assert.Equal("Bob le Bricoleur", (string) response["name"]!); + Assert.Equal("Bob le Bricoleur", (string?) response["name"]); } [Theory] @@ -396,11 +655,13 @@ namespace OpenIddict.Server.Owin.IntegrationTests [InlineData("/.well-known/jwks")] [InlineData("/custom")] [InlineData("/connect/authorize")] + [InlineData("/connect/device")] [InlineData("/connect/introspect")] [InlineData("/connect/logout")] [InlineData("/connect/revoke")] [InlineData("/connect/token")] [InlineData("/connect/userinfo")] + [InlineData("/connect/verification")] public async Task ProcessRequest_AllowsSkippingHandler(string address) { // Arrange @@ -423,7 +684,7 @@ namespace OpenIddict.Server.Owin.IntegrationTests var response = await client.PostAsync(address, new OpenIddictRequest()); // Assert - Assert.Equal("Bob le Magnifique", (string) response["name"]!); + Assert.Equal("Bob le Magnifique", (string?) response["name"]); } [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", From db222863c6d0676a6023a80a10e60cc5985f55f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 7 May 2021 17:39:35 +0200 Subject: [PATCH 4/4] Update Versions.props to build 3.0.4 packages --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 3fa86bdd..0540d703 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -3,7 +3,7 @@ 3 0 - 3 + 4 $(MajorVersion).$(MinorVersion).$(PatchVersion) rtm