private static IServiceCollection AddIdentity(
            this IServiceCollection services,
            Core.IdentityServerOptions options,
            Action <IdentityOptions> identityOptionsAction)
        {
            identityOptionsAction = identityOptionsAction ?? (_ =>
            {
            });
            var builder = services.AddIdentity <User, Role>(identityOptionsAction);

            if (options.UseEntityFramework)
            {
                builder.AddEntityFrameworkStores <IdentityServerDbContext>();
            }

            builder.AddDefaultTokenProviders();
            return(builder.Services);
        }
        private static IServiceCollection AddAuthentication(
            this IServiceCollection services,
            Core.IdentityServerOptions options,
            Action <AspNetCore.Authentication.AuthenticationOptions> authenticationOptionsAction,
            Action <IdentityServerAuthenticationOptions> identityServerAuthenticationOptionsAction,
            Action <FacebookOptions> facebookOptionsAction)
        {
            authenticationOptionsAction = authenticationOptionsAction ?? (authenticationOptions =>
            {
                if (!IsNullOrWhiteSpace(options.DefaultScheme))
                {
                    authenticationOptions.DefaultScheme = options.DefaultScheme;
                }

                if (authenticationOptions.DefaultAuthenticateScheme == default &&
                    authenticationOptions.DefaultScheme == DefaultCookieAuthenticationScheme)
                {
                    authenticationOptions.DefaultScheme = ApplicationScheme;
                }
            });
            var builder = services.AddAuthentication(authenticationOptionsAction);

            if (options.UseIdentityServer4Authentication)
            {
                identityServerAuthenticationOptionsAction = identityServerAuthenticationOptionsAction ?? (_ =>
                {
                });
                builder.AddIdentityServerAuthentication(identityServerAuthenticationOptionsAction);
            }

            if (options.UseFacebookAuthentication)
            {
                facebookOptionsAction = facebookOptionsAction ?? (_ =>
                {
                });
                builder.AddFacebook(facebookOptionsAction);
            }

            return(builder.Services);
        }
        private static IServiceCollection AddIdentityServer(
            this IServiceCollection services,
            Core.IdentityServerOptions identityServerOptions,
            bool isDevelopment,
            Action <IdentityServer4.Configuration.IdentityServerOptions> identityServerOptionsAction,
            Action <ConfigurationStoreOptions> configurationStoreOptionsAction,
            Action <OperationalStoreOptions> operationalStoreOptionsAction,
            Action <IdentityOptions> identityOptionsAction,
            Action <AspNetCore.Authentication.AuthenticationOptions> authenticationOptionsAction,
            Action <IdentityServerAuthenticationOptions> identityServerAuthenticationOptionsAction,
            Action <FacebookOptions> facebookOptionsAction)
        {
            DefaultInboundClaimTypeMap.Clear();
            DefaultOutboundClaimTypeMap.Clear();

            var builder = new IdentityServerBuilder(services);

            identityServerOptionsAction = identityServerOptionsAction ?? (_ =>
            {
            });
            builder.Services.Configure <SecurityStampValidatorOptions>(opts =>
            {
                opts.OnRefreshingPrincipal = UpdatePrincipal;
            });
            builder.Services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.IsEssential = true;
                options.Cookie.SameSite    = None;
            });
            builder.Services.ConfigureExternalCookie(options =>
            {
                options.Cookie.IsEssential = true;
                options.Cookie.SameSite    = None;
            });
            builder.Services.Configure <CookieAuthenticationOptions>(TwoFactorRememberMeScheme, options =>
            {
                options.Cookie.IsEssential = true;
            });
            builder.Services.Configure <CookieAuthenticationOptions>(TwoFactorUserIdScheme, options =>
            {
                options.Cookie.IsEssential = true;
            });
            builder.Services.Configure(identityServerOptionsAction);
            builder.Services.AddIdentityServer();
            if (identityServerOptions.UseEntityFramework)
            {
                builder.Services.AddEntityFramework(configurationStoreOptionsAction, operationalStoreOptionsAction);
                builder.AddConfigurationStore <IdentityServerDbContext>(configurationStoreOptionsAction);
                builder.AddOperationalStore <IdentityServerDbContext>(operationalStoreOptionsAction);
            }

            if (identityServerOptions.UseIdentity)
            {
                builder.Services.AddIdentity(identityServerOptions, identityOptionsAction);
                builder.AddAspNetIdentity <User>();
            }

            if (identityServerOptions.UseAuthentication)
            {
                builder.Services.AddAuthentication(
                    identityServerOptions,
                    authenticationOptionsAction,
                    identityServerAuthenticationOptionsAction,
                    facebookOptionsAction);
            }

            if (isDevelopment)
            {
                builder.AddDeveloperSigningCredential();
            }
            else
            {
                if (!IsNullOrWhiteSpace(identityServerOptions.SigningCredential))
                {
                    var rawData = FromBase64String(identityServerOptions.SigningCredential);
                    var cert    = new X509Certificate2(rawData, default(string), MachineKeySet);
                    builder.AddSigningCredential(cert);
                }

                if (!IsNullOrWhiteSpace(identityServerOptions.ValidationKey))
                {
                    var rawData = FromBase64String(identityServerOptions.ValidationKey);
                    var cert    = new X509Certificate2(rawData, default(string), MachineKeySet);
                    builder.AddValidationKey(cert);
                }

                builder.AddConfigurationStoreCache();
            }

            return(builder.Services);
        }