diff --git a/.editorconfig b/.editorconfig index 547eadea8..164295049 100644 --- a/.editorconfig +++ b/.editorconfig @@ -383,7 +383,7 @@ resharper_csharp_align_multiline_argument=false resharper_csharp_align_multiline_expression=false resharper_csharp_align_multiline_parameter=false resharper_csharp_align_multiple_declaration=false -resharper_csharp_max_line_length=120 +resharper_csharp_max_line_length=160 resharper_csharp_naming_rule.enum_member=AaBb resharper_csharp_naming_rule.method_property_event=AaBb resharper_csharp_naming_rule.other=AaBb @@ -412,7 +412,7 @@ resharper_format_leading_spaces_decl=false resharper_html_attribute_indent=align_by_first_attribute resharper_html_linebreak_before_elements=body,div,p,form,h1,h2,h3 resharper_html_max_blank_lines_between_tags=2 -resharper_html_max_line_length=120 +resharper_html_max_line_length=160 resharper_html_pi_attribute_style=on_single_line resharper_html_space_before_self_closing=false resharper_html_wrap_lines=true @@ -619,7 +619,7 @@ resharper_vb_align_multiline_argument=true resharper_vb_align_multiline_expression=true resharper_vb_align_multiline_parameter=true resharper_vb_align_multiple_declaration=true -resharper_vb_max_line_length=120 +resharper_vb_max_line_length=160 resharper_vb_place_field_attribute_on_same_line=true resharper_vb_place_method_attribute_on_same_line=false resharper_vb_place_type_attribute_on_same_line=false @@ -659,7 +659,7 @@ resharper_wrap_verbatim_interpolated_strings=no_wrap resharper_xmldoc_attribute_indent=single_indent resharper_xmldoc_linebreak_before_elements=summary,remarks,example,returns,param,typeparam,value,para resharper_xmldoc_max_blank_lines_between_tags=0 -resharper_xmldoc_max_line_length=120 +resharper_xmldoc_max_line_length=160 resharper_xmldoc_pi_attribute_style=do_not_touch resharper_xmldoc_space_before_self_closing=true resharper_xmldoc_wrap_lines=true @@ -668,7 +668,7 @@ resharper_xmldoc_wrap_text=true resharper_xml_attribute_indent=align_by_first_attribute resharper_xml_linebreak_before_elements= resharper_xml_max_blank_lines_between_tags=2 -resharper_xml_max_line_length=120 +resharper_xml_max_line_length=160 resharper_xml_pi_attribute_style=do_not_touch resharper_xml_space_before_self_closing=true resharper_xml_wrap_lines=true diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 8a9cab353..043ae849b 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -2,15 +2,15 @@ net8.0 - 8.0.19 + 8.0.27 - - - - + + + + @@ -40,19 +40,19 @@ - + - + - + - - - - - + + + + + diff --git a/src/IdentityServer4/src/Configuration/DependencyInjection/IdentityServerServiceCollectionExtensions.cs b/src/IdentityServer4/src/Configuration/DependencyInjection/IdentityServerServiceCollectionExtensions.cs index ca0ba41b5..81405f295 100644 --- a/src/IdentityServer4/src/Configuration/DependencyInjection/IdentityServerServiceCollectionExtensions.cs +++ b/src/IdentityServer4/src/Configuration/DependencyInjection/IdentityServerServiceCollectionExtensions.cs @@ -5,6 +5,7 @@ using IdentityServer4.Configuration; using Microsoft.Extensions.Configuration; using System; +using Dex.RfcExceptionsHandler.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Authentication.OpenIdConnect; @@ -33,6 +34,8 @@ public static IIdentityServerBuilder AddIdentityServerBuilder(this IServiceColle /// public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services) { + services.AddDefaultRfcExceptionHandleMiddleware(); + var builder = services.AddIdentityServerBuilder(); builder @@ -83,10 +86,9 @@ public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection s /// The schemes to configure. If none provided, then all OpenIdConnect schemes will use the cache. public static IServiceCollection AddOidcStateDataFormatterCache(this IServiceCollection services, params string[] schemes) { - services.AddSingleton>( - svcs => new ConfigureOpenIdConnectOptions( - schemes, - svcs.GetRequiredService()) + services.AddSingleton>(svcs => new ConfigureOpenIdConnectOptions( + schemes, + svcs.GetRequiredService()) ); return services; diff --git a/src/IdentityServer4/src/Configuration/IdentityServerApplicationBuilderExtensions.cs b/src/IdentityServer4/src/Configuration/IdentityServerApplicationBuilderExtensions.cs index 9b8831640..76aa46abb 100644 --- a/src/IdentityServer4/src/Configuration/IdentityServerApplicationBuilderExtensions.cs +++ b/src/IdentityServer4/src/Configuration/IdentityServerApplicationBuilderExtensions.cs @@ -12,6 +12,7 @@ using System; using System.Reflection; using System.Threading.Tasks; +using Dex.RfcExceptionsHandler.Extensions; namespace Microsoft.AspNetCore.Builder; @@ -29,6 +30,7 @@ public static class IdentityServerApplicationBuilderExtensions public static IApplicationBuilder UseIdentityServer(this IApplicationBuilder app, IdentityServerMiddlewareOptions options = null) { app.Validate(); + app.UseRfcExceptionHandleMiddleware(); app.UseMiddleware(); @@ -54,21 +56,26 @@ internal static void Validate(this IApplicationBuilder app) if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); var logger = loggerFactory.CreateLogger("IdentityServer4.Startup"); - logger.LogInformation("Starting IdentityServer4 version {version}", typeof(IdentityServerMiddleware).Assembly.GetCustomAttribute().InformationalVersion); + logger.LogInformation("Starting IdentityServer4 version {version}", + typeof(IdentityServerMiddleware).Assembly.GetCustomAttribute().InformationalVersion); var scopeFactory = app.ApplicationServices.GetService(); using var scope = scopeFactory.CreateScope(); var serviceProvider = scope.ServiceProvider; - TestService(serviceProvider, typeof(IPersistedGrantStore), logger, "No storage mechanism for grants specified. Use the 'AddInMemoryPersistedGrants' extension method to register a development version."); - TestService(serviceProvider, typeof(IClientStore), logger, "No storage mechanism for clients specified. Use the 'AddInMemoryClients' extension method to register a development version."); - TestService(serviceProvider, typeof(IResourceStore), logger, "No storage mechanism for resources specified. Use the 'AddInMemoryIdentityResources' or 'AddInMemoryApiResources' extension method to register a development version."); + TestService(serviceProvider, typeof(IPersistedGrantStore), logger, + "No storage mechanism for grants specified. Use the 'AddInMemoryPersistedGrants' extension method to register a development version."); + TestService(serviceProvider, typeof(IClientStore), logger, + "No storage mechanism for clients specified. Use the 'AddInMemoryClients' extension method to register a development version."); + TestService(serviceProvider, typeof(IResourceStore), logger, + "No storage mechanism for resources specified. Use the 'AddInMemoryIdentityResources' or 'AddInMemoryApiResources' extension method to register a development version."); var persistedGrants = serviceProvider.GetService(typeof(IPersistedGrantStore)); if (persistedGrants.GetType().FullName == typeof(InMemoryPersistedGrantStore).FullName) { - logger.LogInformation("You are using the in-memory version of the persisted grant store. This will store consent decisions, authorization codes, refresh and reference tokens in memory only. If you are using any of those features in production, you want to switch to a different store implementation."); + logger.LogInformation( + "You are using the in-memory version of the persisted grant store. This will store consent decisions, authorization codes, refresh and reference tokens in memory only. If you are using any of those features in production, you want to switch to a different store implementation."); } var options = serviceProvider.GetRequiredService(); @@ -85,7 +92,8 @@ private static async Task ValidateAsync(IServiceProvider services, ILogger logge if (await schemes.GetDefaultAuthenticateSchemeAsync() == null && options.Authentication.CookieAuthenticationScheme == null) { - logger.LogWarning("No authentication scheme has been set. Setting either a default authentication scheme or a CookieAuthenticationScheme on IdentityServerOptions is required."); + logger.LogWarning( + "No authentication scheme has been set. Setting either a default authentication scheme or a CookieAuthenticationScheme on IdentityServerOptions is required."); } else { @@ -94,7 +102,8 @@ private static async Task ValidateAsync(IServiceProvider services, ILogger logge if (options.Authentication.CookieAuthenticationScheme != null) { authenticationScheme = await schemes.GetSchemeAsync(options.Authentication.CookieAuthenticationScheme); - logger.LogInformation("Using explicitly configured authentication scheme {scheme} for IdentityServer", options.Authentication.CookieAuthenticationScheme); + logger.LogInformation("Using explicitly configured authentication scheme {scheme} for IdentityServer", + options.Authentication.CookieAuthenticationScheme); } else { @@ -104,7 +113,9 @@ private static async Task ValidateAsync(IServiceProvider services, ILogger logge if (!typeof(IAuthenticationSignInHandler).IsAssignableFrom(authenticationScheme.HandlerType)) { - logger.LogInformation("Authentication scheme {scheme} is configured for IdentityServer, but it is not a scheme that supports signin (like cookies). If you support interactive logins via the browser, then a cookie-based scheme should be used.", authenticationScheme.Name); + logger.LogInformation( + "Authentication scheme {scheme} is configured for IdentityServer, but it is not a scheme that supports signin (like cookies). If you support interactive logins via the browser, then a cookie-based scheme should be used.", + authenticationScheme.Name); } logger.LogDebug("Using {scheme} as default ASP.NET Core scheme for authentication", (await schemes.GetDefaultAuthenticateSchemeAsync())?.Name); @@ -118,7 +129,7 @@ private static async Task ValidateAsync(IServiceProvider services, ILogger logge private static void ValidateOptions(IdentityServerOptions options, ILogger logger) { if (options.IssuerUri.IsPresent()) logger.LogDebug("Custom IssuerUri set to {0}", options.IssuerUri); - + // todo: perhaps different logging messages? //if (options.UserInteraction.LoginUrl.IsMissing()) throw new InvalidOperationException("LoginUrl is not configured"); //if (options.UserInteraction.LoginReturnUrlParameter.IsMissing()) throw new InvalidOperationException("LoginReturnUrlParameter is not configured"); @@ -128,7 +139,8 @@ private static void ValidateOptions(IdentityServerOptions options, ILogger logge if (options.UserInteraction.ErrorIdParameter.IsMissing()) throw new InvalidOperationException("ErrorIdParameter is not configured"); if (options.UserInteraction.ConsentUrl.IsMissing()) throw new InvalidOperationException("ConsentUrl is not configured"); if (options.UserInteraction.ConsentReturnUrlParameter.IsMissing()) throw new InvalidOperationException("ConsentReturnUrlParameter is not configured"); - if (options.UserInteraction.CustomRedirectReturnUrlParameter.IsMissing()) throw new InvalidOperationException("CustomRedirectReturnUrlParameter is not configured"); + if (options.UserInteraction.CustomRedirectReturnUrlParameter.IsMissing()) + throw new InvalidOperationException("CustomRedirectReturnUrlParameter is not configured"); if (options.Authentication.CheckSessionCookieName.IsMissing()) throw new InvalidOperationException("CheckSessionCookieName is not configured"); diff --git a/src/IdentityServer4/src/IdentityServer4.csproj b/src/IdentityServer4/src/IdentityServer4.csproj index 66b44a667..896d5a338 100644 --- a/src/IdentityServer4/src/IdentityServer4.csproj +++ b/src/IdentityServer4/src/IdentityServer4.csproj @@ -41,6 +41,7 @@ + diff --git a/src/IdentityServer4/test/IdentityServer.IntegrationTests/Endpoints/Authorize/AuthorizeTests.cs b/src/IdentityServer4/test/IdentityServer.IntegrationTests/Endpoints/Authorize/AuthorizeTests.cs index c04f38037..16c046b41 100644 --- a/src/IdentityServer4/test/IdentityServer.IntegrationTests/Endpoints/Authorize/AuthorizeTests.cs +++ b/src/IdentityServer4/test/IdentityServer.IntegrationTests/Endpoints/Authorize/AuthorizeTests.cs @@ -1058,8 +1058,8 @@ public async Task overlapping_identity_scopes_and_api_scopes_should_show_error_p "123_state", "123_nonce"); - Func a = () => _mockPipeline.BrowserClient.GetAsync(url, TestContext.Current.CancellationToken); - await a.Should().ThrowAsync(); + var response = await _mockPipeline.BrowserClient.GetAsync(url, TestContext.Current.CancellationToken); + response.StatusCode.Should().Be(HttpStatusCode.InternalServerError); } [Fact]