using System.Collections.Generic; using IdentityServer4; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using xCommons.Authorization; using xCommons.Constants; using xCommons.Extensions; using xExceptions.Constants; using xIdentityHelper; using xIdentityModels; using xIdentityModels.Configurations; using xIds.Configurations; using xIds.Constants; using xIds.DbContext; using xIds.Extensions; using xIds.Helpers; using xIds.Interfaces; using xIds.Providers; using xIds.Validators; using xMessageService.DI; using xMessageService.Interfaces; using xStorageService.DI; using xStorageService.Interfaces; namespace xIds.DI { public static class XDIHelperExtension { /// /// Register Application DataProvider /// /// /// public static void AddXDataProvider( this IServiceCollection services, IConfiguration configuration ) { // // Retrieve DbInfo ... var dbInfo = configuration.GetXDbInfo(); var identityDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.IDENTITY_CONNECTION_NAME); // // Register Db Context for EF ... services.AddDbContext(builder => { // builder.PrepareXDbContextOptionsBuilder( dbInfo, identityDbConnectionString ); }); } /// /// Extract Connection String From IConfiguration /// /// /// /// public static string GetXConnectionString( this IConfiguration config, string connectionName = null ) { // if (connectionName.IsNullOrEmpty()) { connectionName = XDbProviderConfigurations.DEFAULT_CONNECTION_NAME; } // return config.GetConnectionString(connectionName); } /// /// Retrive XDataService Configurations /// /// /// /// public static XDataServiceConfiguration GetXDataServiceConfiguration( this IConfiguration source, string connectionName = null ) { // var xDataServiceConfigSection = source .GetSection(Constants.ConfigurationNodeNames.DATA_SERVICE_NODE_NAME); var result = xDataServiceConfigSection.Get(); if (result.IsNull()) { result = new XDataServiceConfiguration(); } // result.Provider = source.GetXDbProviderType(); result.ConnectionString = source.GetXConnectionString(connectionName); // return result; } /// /// Register XDataService Configuration /// /// /// /// public static void AddXDataServiceConfiguration( this IServiceCollection services, IConfiguration configuration, string connectionName = null ) { // var dataServiceConfiguration = configuration .GetXDataServiceConfiguration(connectionName); // services.AddSingleton(dataServiceConfiguration); } /// /// Register All Requirements For XIdentityServer Usage /// /// /// public static void AddXIdentityServerRequirements( this IServiceCollection services, IConfiguration configuration ) { // services.AddXDataProvider(configuration); // // Register XIdentityMessageProvider ... services.AddXIdentityMessageProvider(); // // Register IdentityManager Service ... var xIdentityManager = services.GetRegisteredService(); if (xIdentityManager.IsNull()) { services.AddXIdentityManager(); } // // Check XMessage Service Registered or not and Register it if not ... var xMessageProvider = services.GetRegisteredService(); if (xMessageProvider.IsNull()) { services.AddXMessageService(configuration); } // // Check Storage Service Registered or not and Register it if not ... var xStorageProvider = services.GetRegisteredService(); if (xStorageProvider.IsNull()) { services.AddXStorageService(configuration); } // // Register XIdentityConfiguration ... var xIdentityConfiguration = configuration.GetXIdentityConfiguration(); services.AddSingleton(xIdentityConfiguration); // // Register XIdentityHelper ... services.AddSingleton(); var xIdentityHelper = services.GetRegisteredService(); // // Register Asp.net Identity ... services.AddXIdentity(); } /// /// Add IdentityServer with Support of Ef /// /// /// public static void AddEfSupportXIdentityServer( this IServiceCollection services, IConfiguration configuration ) { // // Register All Requirements ... services.AddXIdentityServerRequirements(configuration); // // add DbSeeder Config ... services.AddXDebSeederDescriptor(configuration); // // Retrieve Certificate ... var identityServerSigningCertificate = configuration.GetCertificate(CertificatesConfigurations.CertificateNames.IdentityServerSigning); // // Retrieve DbInfo ... var dbInfo = configuration.GetXDbInfo(); // // Retrieve Connection String Names ... var configDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.CONFIGURATION_CONNECTION_NAME); var persistedGrantDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.PRESISTED_GRANTS_CONNECTION_NAME); // // Register IdentityServer ... services.AddIdentityServer(options => { // options.Discovery.CustomEntries.Add("account_api", "~/account"); // // options.Events.RaiseErrorEvents = true; // options.Events.RaiseFailureEvents = true; // options.Events.RaiseSuccessEvents = true; // options.Events.RaiseInformationEvents = true; }) .LoadSigningCredentialFrom(identityServerSigningCertificate) .AddXDbProvider(configuration) .AddAspNetIdentity() .AddProfileService() .AddResourceOwnerValidator(); } /// /// force app to use IdentityServer /// /// /// public static void UseXIdentityServer( this IApplicationBuilder app, ILogger logger ) { // // Update XIdentityServer Configurations before Use Identity Server ... app.SeedData(logger) .GetAwaiter() .GetResult(); // // Use Identity Server ... app.UseIdentityServer(); } /// /// Register Asp.net Identity as User Store /// /// public static void AddXIdentity(this IServiceCollection services) { // var xIdentityConfiguration = services.GetRegisteredService(); if (xIdentityConfiguration.IsNull()) { XException.InvalidConfiguration.Throw(); } // var xIdentityHelper = services.GetRegisteredService(); if (xIdentityHelper.IsNull()) { XException.InvalidConfiguration.Throw(); } // // Add Identity for User Persists ... services.AddIdentity(options => { // var mLockoutSpan = xIdentityHelper.GetLockoutTimeSpan(); // // Lockout Setting ... options.Lockout.DefaultLockoutTimeSpan = mLockoutSpan; options.Lockout.MaxFailedAccessAttempts = xIdentityConfiguration.Policy.Lockout.MaxFailedAccessAttempts; options.Lockout.AllowedForNewUsers = xIdentityConfiguration.Policy.Lockout.AllowedForNewUsers; // // Password settings ... options.Password.RequireDigit = xIdentityConfiguration.Policy.Password.RequireDigit; options.Password.RequireLowercase = xIdentityConfiguration.Policy.Password.RequireLowercase; options.Password.RequireNonAlphanumeric = xIdentityConfiguration.Policy.Password.RequireNonAlphanumeric; options.Password.RequireUppercase = xIdentityConfiguration.Policy.Password.RequireUppercase; options.Password.RequiredLength = xIdentityConfiguration.Policy.Password.RequiredLength; options.Password.RequiredUniqueChars = xIdentityConfiguration.Policy.Password.RequiredUniqueChars; // // SignIn settings ... options.SignIn.RequireConfirmedEmail = xIdentityConfiguration.Policy.SignIn.RequireConfirmedEmail; options.SignIn.RequireConfirmedPhoneNumber = xIdentityConfiguration.Policy.SignIn.RequireConfirmedPhoneNumber; // // User settings ... options.User.AllowedUserNameCharacters = xIdentityConfiguration.Policy.User.AllowedUserNameCharacters; options.User.RequireUniqueEmail = xIdentityConfiguration.Policy.User.RequireUniqueEmail; }) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); } /// /// Register IdentityServer Based Authentication /// /// /// public static void AddXIdentityServerAuthentication( this IServiceCollection services, IConfiguration configuration ) { // services.AddXIdentityResourceConfiguration(configuration); services.AddAuthentication() .AddJwtBearer(options => { // options.SaveToken = true; options.RequireHttpsMetadata = false; // options.ForwardDefault = XAuthentication.IDENTITY_SERVER_LOCAL_API; }) .AddLocalApi(); } /// /// Register Authorization Policies /// /// /// public static void AddXAuthorization( this IServiceCollection services, IDictionary policies = null ) { // services.AddAuthorization(options => { // if (!policies.IsNull()) { // // Fill Policies ... using (var policiesEnumerator = policies.GetEnumerator()) { while (policiesEnumerator.MoveNext()) { var policyDescriptor = policiesEnumerator.Current; options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value); } } } // var xPolicies = XAuthorizationHelper.GetXAuthorizationPolicies(); if (!xPolicies.IsNull()) { // // Fill Policies ... using (var policiesEnumerator = xPolicies.GetEnumerator()) { while (policiesEnumerator.MoveNext()) { var policyDescriptor = policiesEnumerator.Current; options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value); } } } // // Add Local APi Policy ... options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy => { // policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme); policy.RequireAuthenticatedUser(); }); }); // services.AddSingleton(); } /// /// Use Forward Headers Options for resolving behind a proxy issues ... /// /// /// public static void UseXForwardOptions(this IApplicationBuilder source) { // var forwardOptions = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, RequireHeaderSymmetry = false }; // forwardOptions.KnownNetworks.Clear(); forwardOptions.KnownProxies.Clear(); // // ref: https://github.com/aspnet/Docs/issues/2384 source.UseForwardedHeaders(forwardOptions); } } }