public static OpenIddictBuilder AddModule(
            [NotNull] this OpenIddictBuilder builder,
            [NotNull] string name, int position,
            [NotNull] Action <IApplicationBuilder> registration)
        {
            // Note: always call ToArray to make sure the foreach
            // block doesn't iterate on the modified collection.
            foreach (var module in builder.Modules.Where(module => string.Equals(module.Name, name)).ToArray())
            {
                builder.Modules.Remove(module);
            }

            builder.Modules.Add(new OpenIddictModule {
                Name         = name,
                Position     = position,
                Registration = registration
            });

            return(builder);
        }
        public static OpenIddictBuilder UseNWebsec(
            [NotNull] this OpenIddictBuilder builder,
            [NotNull] Action <IFluentCspOptions> configuration)
        {
            return(builder.AddModule("NWebsec", 5, app => {
                // Insert a new middleware responsible of setting the Content-Security-Policy header.
                // See https://nwebsec.codeplex.com/wikipage?title=Configuring%20Content%20Security%20Policy&referringTitle=NWebsec
                app.UseCsp(configuration);

                // Insert a new middleware responsible of setting the X-Content-Type-Options header.
                // See https://nwebsec.codeplex.com/wikipage?title=Configuring%20security%20headers&referringTitle=NWebsec
                app.UseXContentTypeOptions();

                // Insert a new middleware responsible of setting the X-Frame-Options header.
                // See https://nwebsec.codeplex.com/wikipage?title=Configuring%20security%20headers&referringTitle=NWebsec
                app.UseXfo(options => options.Deny());

                // Insert a new middleware responsible of setting the X-Xss-Protection header.
                // See https://nwebsec.codeplex.com/wikipage?title=Configuring%20security%20headers&referringTitle=NWebsec
                app.UseXXssProtection(options => options.EnabledWithBlockMode());
            }));
        }
        public static OpenIddictBuilder UseMvc([NotNull] this OpenIddictBuilder builder)
        {
            // Run MVC in an isolated environment.
            return(builder.AddModule("MVC", 10, app => app.Isolate(map => map.UseMvc(routes => {
                // Register the actions corresponding to the authorization endpoint.
                if (builder.Options.AuthorizationEndpointPath.HasValue)
                {
                    routes.MapRoute("{D97891B4}", builder.Options.AuthorizationEndpointPath.Value.Substring(1), new {
                        controller = "OpenIddict", action = nameof(OpenIddictController <object, object> .Authorize)
                    });

                    routes.MapRoute("{7148DB83}", builder.Options.AuthorizationEndpointPath.Value.Substring(1) + "/accept", new {
                        controller = "OpenIddict", action = nameof(OpenIddictController <object, object> .Accept)
                    });

                    routes.MapRoute("{23438BCC}", builder.Options.AuthorizationEndpointPath.Value.Substring(1) + "/deny", new {
                        controller = "OpenIddict", action = nameof(OpenIddictController <object, object> .Deny)
                    });
                }

                // Register the action corresponding to the logout endpoint.
                if (builder.Options.LogoutEndpointPath.HasValue)
                {
                    routes.MapRoute("{C7DB102A}", builder.Options.LogoutEndpointPath.Value.Substring(1), new {
                        controller = "OpenIddict", action = nameof(OpenIddictController <object, object> .Logout)
                    });
                }
            }), services => {
                var registration = app.ApplicationServices.GetRequiredService <OpenIddictServices>();

                services.AddMvc()
                // Register the OpenIddict controller.
                .AddControllersAsServices(new[] {
                    typeof(OpenIddictController <,>).MakeGenericType(registration.UserType, registration.ApplicationType)
                })

                // Add an OpenIddict-specific convention to ensure that the generic
                // OpenIddictController gets an appropriate controller name.
                .AddMvcOptions(options => options.Conventions.Add(new OpenIddictConvention()))

                .AddRazorOptions(options => {
                    // Update the Razor options to also use a combined provider that
                    // falls back to the current assembly when searching for views.
                    options.FileProvider = new CompositeFileProvider(
                        options.FileProvider,
                        new EmbeddedFileProvider(
                            assembly: typeof(OpenIddictController <,>).GetTypeInfo().Assembly,
                            baseNamespace: typeof(OpenIddictController <,>).Namespace));
                });

                // Register the sign-in manager in the isolated container.
                services.AddScoped(typeof(SignInManager <>).MakeGenericType(registration.UserType), provider => {
                    var accessor = provider.GetRequiredService <IHttpContextAccessor>();
                    var container = (IServiceProvider)accessor.HttpContext.Items[typeof(IServiceProvider)];
                    Debug.Assert(container != null);

                    // Resolve the sign-in manager from the parent container.
                    return container.GetRequiredService(typeof(SignInManager <>).MakeGenericType(registration.UserType));
                });

                // Register the user manager in the isolated container.
                services.AddScoped(typeof(OpenIddictManager <,>).MakeGenericType(registration.UserType, registration.ApplicationType), provider => {
                    var accessor = provider.GetRequiredService <IHttpContextAccessor>();
                    var container = (IServiceProvider)accessor.HttpContext.Items[typeof(IServiceProvider)];
                    Debug.Assert(container != null);

                    // Resolve the user manager from the parent container.
                    return container.GetRequiredService(typeof(OpenIddictManager <,>).MakeGenericType(registration.UserType, registration.ApplicationType));
                });

                // Register the options in the isolated container.
                services.AddScoped(provider => builder.Options);
            })));
        }