using Bit.Core.Auth.PasswordValidation; using Bit.Core.Auth.Repositories; using Bit.Core.Entities; using Bit.Core.IdentityServer; using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.Identity.IdentityServer; using Bit.Identity.IdentityServer.ClientProviders; using Bit.Identity.IdentityServer.RequestValidators; using Bit.SharedWeb.Utilities; using Duende.IdentityServer.ResponseHandling; using Duende.IdentityServer.Services; using Duende.IdentityServer.Stores; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection.Extensions; namespace Bit.Identity.Utilities; public static class ServiceCollectionExtensions { public static IIdentityServerBuilder AddCustomIdentityServerServices(this IServiceCollection services, IWebHostEnvironment env, GlobalSettings globalSettings) { services.AddTransient(); services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); var issuerUri = new Uri(globalSettings.BaseServiceUri.InternalIdentity); var identityServerBuilder = services .AddIdentityServer(options => { options.LicenseKey = globalSettings.IdentityServer.LicenseKey; options.Endpoints.EnableIntrospectionEndpoint = false; options.Endpoints.EnableEndSessionEndpoint = false; options.Endpoints.EnableUserInfoEndpoint = false; options.Endpoints.EnableCheckSessionEndpoint = false; options.Endpoints.EnableTokenRevocationEndpoint = false; options.IssuerUri = $"{issuerUri.Scheme}://{issuerUri.Host}"; options.Caching.ClientStoreExpiration = new TimeSpan(0, 5, 0); if (env.IsDevelopment()) { options.Authentication.CookieSameSiteMode = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified; } options.InputLengthRestrictions.UserName = 256; options.KeyManagement.Enabled = false; options.UserInteraction.LoginUrl = "/sso/Login"; }) .AddInMemoryCaching() .AddInMemoryApiResources(ApiResources.GetApiResources()) .AddInMemoryApiScopes(ApiScopes.GetApiScopes()) .AddClientStoreCache() .AddCustomTokenRequestValidator() .AddProfileService() .AddResourceOwnerValidator() .AddClientStore() .AddIdentityServerCertificate(env, globalSettings) .AddExtensionGrantValidator() .AddExtensionGrantValidator(); // ExtensionGrantValidator Dependencies services.TryAddScoped, PasswordHasher>(); services.Configure(options => options.IterationCount = PasswordValidationConstants.PasswordHasherKdfIterations); if (!globalSettings.SelfHosted) { // Only cloud instances should be able to handle installations services.AddClientProvider("installation"); } if (globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey)) { services.AddClientProvider("internal"); } services.AddClientProvider("user"); services.AddClientProvider("organization"); services.AddClientProvider(SecretsManagerApiKeyProvider.ApiKeyPrefix); if (CoreHelpers.SettingHasValue(globalSettings.IdentityServer.CosmosConnectionString)) { services.AddSingleton(sp => new PersistedGrantStore(sp.GetRequiredKeyedService("cosmos"), g => new Core.Auth.Models.Data.GrantItem(g))); } else { services.AddTransient(sp => new PersistedGrantStore(sp.GetRequiredService(), g => new Core.Auth.Entities.Grant(g))); } services.AddTransient(); return identityServerBuilder; } }