Files
xSaherElmIds/DI/XDIHelperExtension.cs
2026-03-22 14:08:25 +03:30

420 lines
15 KiB
C#

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
{
/// <summary>
/// Register Application DataProvider
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
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<XIdentityDbContext>(builder =>
{
//
builder.PrepareXDbContextOptionsBuilder(
dbInfo,
identityDbConnectionString
);
});
}
/// <summary>
/// Extract Connection String From IConfiguration
/// </summary>
/// <param name="config"></param>
/// <param name="connectionName"></param>
/// <returns></returns>
public static string GetXConnectionString(
this IConfiguration config,
string connectionName = null
)
{
//
if (connectionName.IsNullOrEmpty())
{
connectionName = XDbProviderConfigurations.DEFAULT_CONNECTION_NAME;
}
//
return config.GetConnectionString(connectionName);
}
/// <summary>
/// Retrive XDataService Configurations
/// </summary>
/// <param name="source"></param>
/// <param name="connectionName"></param>
/// <returns></returns>
public static XDataServiceConfiguration GetXDataServiceConfiguration(
this IConfiguration source,
string connectionName = null
)
{
//
var xDataServiceConfigSection = source
.GetSection(Constants.ConfigurationNodeNames.DATA_SERVICE_NODE_NAME);
var result = xDataServiceConfigSection.Get<XDataServiceConfiguration>();
if (result.IsNull())
{
result = new XDataServiceConfiguration();
}
//
result.Provider = source.GetXDbProviderType();
result.ConnectionString = source.GetXConnectionString(connectionName);
//
return result;
}
/// <summary>
/// Register XDataService Configuration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="connectionName"></param>
public static void AddXDataServiceConfiguration(
this IServiceCollection services,
IConfiguration configuration,
string connectionName = null
)
{
//
var dataServiceConfiguration = configuration
.GetXDataServiceConfiguration(connectionName);
//
services.AddSingleton<XDataServiceConfiguration>(dataServiceConfiguration);
}
/// <summary>
/// Register All Requirements For XIdentityServer Usage
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXIdentityServerRequirements(
this IServiceCollection services,
IConfiguration configuration
)
{
//
services.AddXDataProvider(configuration);
//
// Register XIdentityMessageProvider ...
services.AddXIdentityMessageProvider();
//
// Register IdentityManager Service ...
var xIdentityManager = services.GetRegisteredService<IXIdentityManager>();
if (xIdentityManager.IsNull())
{
services.AddXIdentityManager();
}
//
// Check XMessage Service Registered or not and Register it if not ...
var xMessageProvider = services.GetRegisteredService<IXMessageProvider>();
if (xMessageProvider.IsNull())
{
services.AddXMessageService(configuration);
}
//
// Check Storage Service Registered or not and Register it if not ...
var xStorageProvider = services.GetRegisteredService<IXStorageProvider>();
if (xStorageProvider.IsNull())
{
services.AddXStorageService(configuration);
}
//
// Register XIdentityConfiguration ...
var xIdentityConfiguration = configuration.GetXIdentityConfiguration();
services.AddSingleton<XIdentityConfiguration>(xIdentityConfiguration);
//
// Register XIdentityHelper ...
services.AddSingleton<IXIdentityHelper, XIdentityHelper>();
var xIdentityHelper = services.GetRegisteredService<IXIdentityHelper>();
//
// Register Asp.net Identity ...
services.AddXIdentity();
}
/// <summary>
/// Add IdentityServer with Support of Ef
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
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<XUser>()
.AddProfileService<XIdentityProfileService>()
.AddResourceOwnerValidator<XResourceOwnerPasswordValidator>();
}
/// <summary>
/// force app to use IdentityServer
/// </summary>
/// <param name="app"></param>
/// <param name="logger"></param>
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();
}
/// <summary>
/// Register Asp.net Identity as User Store
/// </summary>
/// <param name="services"></param>
public static void AddXIdentity(this IServiceCollection services)
{
//
var xIdentityConfiguration = services.GetRegisteredService<XIdentityConfiguration>();
if (xIdentityConfiguration.IsNull())
{
XException.InvalidConfiguration.Throw();
}
//
var xIdentityHelper = services.GetRegisteredService<IXIdentityHelper>();
if (xIdentityHelper.IsNull())
{
XException.InvalidConfiguration.Throw();
}
//
// Add Identity for User Persists ...
services.AddIdentity<XUser, IdentityRole>(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<XIdentityDbContext>()
.AddDefaultTokenProviders();
}
/// <summary>
/// Register IdentityServer Based Authentication
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
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();
}
/// <summary>
/// Register Authorization Policies
/// </summary>
/// <param name="services"></param>
/// <param name="policies"></param>
public static void AddXAuthorization(
this IServiceCollection services,
IDictionary<string, AuthorizationPolicy> 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<IAuthorizationHandler, RequiredRolesHandler>();
}
/// <summary>
/// Use Forward Headers Options for resolving behind a proxy issues ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
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);
}
}
}