From beb153cb11de89b619013909cba4331c37d41b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 15 Dec 2022 15:48:13 +0100 Subject: [PATCH] Add OpenIddictClientOwinBuilder.SetCookieManager() to simplify replacing the default cookie manager --- .../Startup.cs | 61 ++--- .../Startup.cs | 215 +++++++++--------- .../OpenIddictClientOwinBuilder.cs | 15 ++ 3 files changed, 152 insertions(+), 139 deletions(-) diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs index aef2e3e3..f7ab0807 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs @@ -1,9 +1,11 @@ using System; +using System.Threading.Tasks; using System.Web.Mvc; using Autofac; using Autofac.Extensions.DependencyInjection; using Autofac.Integration.Mvc; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Owin.Host.SystemWeb; using Microsoft.Owin.Security.Cookies; using OpenIddict.Client; using OpenIddict.Client.Owin; @@ -16,34 +18,6 @@ namespace OpenIddict.Sandbox.AspNet.Client public partial class Startup { public void Configuration(IAppBuilder app) - { - var container = CreateContainer(); - - // Register the Autofac scope injector middleware. - app.UseAutofacLifetimeScopeInjector(container); - - // Register the cookie middleware responsible for storing the user sessions. - app.UseCookieAuthentication(new CookieAuthenticationOptions - { - ExpireTimeSpan = TimeSpan.FromMinutes(50), - SlidingExpiration = false - }); - - // Register the OpenIddict middleware. - app.UseMiddlewareFromContainer(); - - // Configure ASP.NET MVC 5.2 to use Autofac when activating controller instances. - DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); - - // Create the database used by the OpenIddict client stack to store tokens. - // Note: in a real world application, this step should be part of a setup script. - using var scope = container.BeginLifetimeScope(); - - var context = scope.Resolve(); - context.Database.CreateIfNotExists(); - } - - private static IContainer CreateContainer() { var services = new ServiceCollection(); @@ -94,7 +68,8 @@ namespace OpenIddict.Sandbox.AspNet.Client // Register the OWIN host and configure the OWIN-specific options. options.UseOwin() .EnableRedirectionEndpointPassthrough() - .EnablePostLogoutRedirectionEndpointPassthrough(); + .EnablePostLogoutRedirectionEndpointPassthrough() + .SetCookieManager(new SystemWebCookieManager()); // Register the System.Net.Http integration and use the identity of the current // assembly as a more specific user agent, which can be useful when dealing with @@ -147,7 +122,33 @@ namespace OpenIddict.Sandbox.AspNet.Client // Register the MVC controllers. builder.RegisterControllers(typeof(Startup).Assembly); - return builder.Build(); + var container = builder.Build(); + + // Register the Autofac scope injector middleware. + app.UseAutofacLifetimeScopeInjector(container); + + // Register the cookie middleware responsible for storing the user sessions. + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + ExpireTimeSpan = TimeSpan.FromMinutes(50), + SlidingExpiration = false + }); + + // Register the OpenIddict middleware. + app.UseMiddlewareFromContainer(); + + // Configure ASP.NET MVC 5.2 to use Autofac when activating controller instances. + DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); + + // Create the database used by the OpenIddict client stack to store tokens. + // Note: in a real world application, this step should be part of a setup script. + Task.Run(async delegate + { + await using var scope = container.BeginLifetimeScope(); + + var context = scope.Resolve(); + context.Database.CreateIfNotExists(); + }).GetAwaiter().GetResult(); } } } diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs index f791627f..fcc07683 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs @@ -8,6 +8,7 @@ using Autofac.Integration.Mvc; using Autofac.Integration.WebApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Owin; +using Microsoft.Owin.Host.SystemWeb; using OpenIddict.Abstractions; using OpenIddict.Client.Owin; using OpenIddict.Sandbox.AspNet.Server.Models; @@ -22,113 +23,6 @@ namespace OpenIddict.Sandbox.AspNet.Server public partial class Startup { public void Configuration(IAppBuilder app) - { - ConfigureAuth(app); - - var container = CreateContainer(); - - // Register the Autofac scope injector middleware. - app.UseAutofacLifetimeScopeInjector(container); - - // Register the OpenIddict middleware. - app.UseMiddlewareFromContainer(); - app.UseMiddlewareFromContainer(); - app.UseMiddlewareFromContainer(); - - // Configure ASP.NET MVC 5.2 to use Autofac when activating controller instances. - DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); - - // Configure ASP.NET MVC 5.2 to use Autofac when activating controller instances - // and infer the Web API routes using the HTTP attributes used in the controllers. - var configuration = new HttpConfiguration - { - DependencyResolver = new AutofacWebApiDependencyResolver(container) - }; - - configuration.MapHttpAttributeRoutes(); - - // Register the Autofac Web API integration and Web API middleware. - app.UseAutofacWebApi(configuration); - app.UseWebApi(configuration); - - // Seed the database with the sample client using the OpenIddict application manager. - // Note: in a real world application, this step should be part of a setup script. - Task.Run(async delegate - { - using var scope = container.BeginLifetimeScope(); - - var context = scope.Resolve(); - context.Database.CreateIfNotExists(); - - var manager = scope.Resolve(); - - if (await manager.FindByClientIdAsync("mvc") is null) - { - await manager.CreateAsync(new OpenIddictApplicationDescriptor - { - ClientId = "mvc", - ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654", - ConsentType = ConsentTypes.Explicit, - DisplayName = "MVC client application", - RedirectUris = - { - new Uri("https://localhost:44378/callback/login/local") - }, - PostLogoutRedirectUris = - { - new Uri("https://localhost:44378/callback/logout/local") - }, - Permissions = - { - Permissions.Endpoints.Authorization, - Permissions.Endpoints.Logout, - Permissions.Endpoints.Token, - Permissions.GrantTypes.AuthorizationCode, - Permissions.GrantTypes.RefreshToken, - Permissions.ResponseTypes.Code, - Permissions.Scopes.Email, - Permissions.Scopes.Profile, - Permissions.Scopes.Roles, - Permissions.Prefixes.Scope + "demo_api" - }, - Requirements = - { - Requirements.Features.ProofKeyForCodeExchange - } - }); - } - - if (await manager.FindByClientIdAsync("postman") is null) - { - await manager.CreateAsync(new OpenIddictApplicationDescriptor - { - ClientId = "postman", - ConsentType = ConsentTypes.Systematic, - DisplayName = "Postman", - RedirectUris = - { - new Uri("https://oauth.pstmn.io/v1/callback") - }, - Permissions = - { - Permissions.Endpoints.Authorization, - Permissions.Endpoints.Device, - Permissions.Endpoints.Token, - Permissions.GrantTypes.AuthorizationCode, - Permissions.GrantTypes.DeviceCode, - Permissions.GrantTypes.Password, - Permissions.GrantTypes.RefreshToken, - Permissions.ResponseTypes.Code, - Permissions.Scopes.Email, - Permissions.Scopes.Profile, - Permissions.Scopes.Roles - } - }); - } - }).GetAwaiter().GetResult(); - } - - private static IContainer CreateContainer() { var services = new ServiceCollection(); @@ -169,7 +63,8 @@ namespace OpenIddict.Sandbox.AspNet.Server // Register the OWIN host and configure the OWIN-specific options. options.UseOwin() - .EnableRedirectionEndpointPassthrough(); + .EnableRedirectionEndpointPassthrough() + .SetCookieManager(new SystemWebCookieManager()); // Register the System.Net.Http integration and use the identity of the current // assembly as a more specific user agent, which can be useful when dealing with @@ -244,7 +139,109 @@ namespace OpenIddict.Sandbox.AspNet.Server // Register the Web API controllers. builder.RegisterApiControllers(typeof(Startup).Assembly); - return builder.Build(); + var container = builder.Build(); + + // Register the Autofac scope injector middleware. + app.UseAutofacLifetimeScopeInjector(container); + + ConfigureAuth(app); + + // Register the OpenIddict middleware. + app.UseMiddlewareFromContainer(); + app.UseMiddlewareFromContainer(); + app.UseMiddlewareFromContainer(); + + // Configure ASP.NET MVC 5.2 to use Autofac when activating controller instances. + DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); + + // Configure ASP.NET MVC 5.2 to use Autofac when activating controller instances + // and infer the Web API routes using the HTTP attributes used in the controllers. + var configuration = new HttpConfiguration + { + DependencyResolver = new AutofacWebApiDependencyResolver(container) + }; + + configuration.MapHttpAttributeRoutes(); + + // Register the Autofac Web API integration and Web API middleware. + app.UseAutofacWebApi(configuration); + app.UseWebApi(configuration); + + // Seed the database with the sample client using the OpenIddict application manager. + // Note: in a real world application, this step should be part of a setup script. + Task.Run(async delegate + { + await using var scope = container.BeginLifetimeScope(); + + var context = scope.Resolve(); + context.Database.CreateIfNotExists(); + + var manager = scope.Resolve(); + + if (await manager.FindByClientIdAsync("mvc") is null) + { + await manager.CreateAsync(new OpenIddictApplicationDescriptor + { + ClientId = "mvc", + ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654", + ConsentType = ConsentTypes.Explicit, + DisplayName = "MVC client application", + RedirectUris = + { + new Uri("https://localhost:44378/callback/login/local") + }, + PostLogoutRedirectUris = + { + new Uri("https://localhost:44378/callback/logout/local") + }, + Permissions = + { + Permissions.Endpoints.Authorization, + Permissions.Endpoints.Logout, + Permissions.Endpoints.Token, + Permissions.GrantTypes.AuthorizationCode, + Permissions.GrantTypes.RefreshToken, + Permissions.ResponseTypes.Code, + Permissions.Scopes.Email, + Permissions.Scopes.Profile, + Permissions.Scopes.Roles, + Permissions.Prefixes.Scope + "demo_api" + }, + Requirements = + { + Requirements.Features.ProofKeyForCodeExchange + } + }); + } + + if (await manager.FindByClientIdAsync("postman") is null) + { + await manager.CreateAsync(new OpenIddictApplicationDescriptor + { + ClientId = "postman", + ConsentType = ConsentTypes.Systematic, + DisplayName = "Postman", + RedirectUris = + { + new Uri("https://oauth.pstmn.io/v1/callback") + }, + Permissions = + { + Permissions.Endpoints.Authorization, + Permissions.Endpoints.Device, + Permissions.Endpoints.Token, + Permissions.GrantTypes.AuthorizationCode, + Permissions.GrantTypes.DeviceCode, + Permissions.GrantTypes.Password, + Permissions.GrantTypes.RefreshToken, + Permissions.ResponseTypes.Code, + Permissions.Scopes.Email, + Permissions.Scopes.Profile, + Permissions.Scopes.Roles + } + }); + } + }).GetAwaiter().GetResult(); } } } diff --git a/src/OpenIddict.Client.Owin/OpenIddictClientOwinBuilder.cs b/src/OpenIddict.Client.Owin/OpenIddictClientOwinBuilder.cs index f39234b3..6d6612d0 100644 --- a/src/OpenIddict.Client.Owin/OpenIddictClientOwinBuilder.cs +++ b/src/OpenIddict.Client.Owin/OpenIddictClientOwinBuilder.cs @@ -88,6 +88,21 @@ public sealed class OpenIddictClientOwinBuilder public OpenIddictClientOwinBuilder EnableErrorPassthrough() => Configure(options => options.EnableErrorPassthrough = true); + /// + /// Sets the cookie manager used to read and write the cookies produced by the OWIN host. + /// + /// The cookie manager to use. + /// The instance. + public OpenIddictClientOwinBuilder SetCookieManager(ICookieManager manager) + { + if (manager is null) + { + throw new ArgumentNullException(nameof(manager)); + } + + return Configure(options => options.CookieManager = manager); + } + /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object? obj) => base.Equals(obj);