using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Core; using Umbraco.Core.BackOffice; using Umbraco.Core.Configuration; using Umbraco.Core.Security; using Umbraco.Core.Serialization; using Umbraco.Net; using Umbraco.Web.BackOffice.Security; using Umbraco.Web.Common.AspNetCore; namespace Umbraco.Extensions { public static class UmbracoBackOfficeServiceCollectionExtensions { /// /// Adds the services required for running the Umbraco back office /// /// public static void AddUmbracoBackOffice(this IServiceCollection services) { services.AddAntiforgery(); } /// /// Adds the services required for using Umbraco back office Identity /// /// public static void AddUmbracoBackOfficeIdentity(this IServiceCollection services) { services.AddDataProtection(); services.TryAddScoped(); services.BuildUmbracoBackOfficeIdentity() .AddDefaultTokenProviders() .AddUserStore() .AddUserManager() .AddSignInManager() .AddClaimsPrincipalFactory>(); // Configure the options specifically for the UmbracoBackOfficeIdentityOptions instance services.ConfigureOptions(); //services.TryAddScoped>(); services .AddAuthentication(Constants.Security.BackOfficeAuthenticationType) .AddCookie(Constants.Security.BackOfficeAuthenticationType); services.ConfigureOptions(); } private static IdentityBuilder BuildUmbracoBackOfficeIdentity(this IServiceCollection services) { // Borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Extensions.Core/src/IdentityServiceCollectionExtensions.cs#L33 // The reason we need our own is because the Identity system doesn't cater easily for multiple identity systems and particularly being // able to configure IdentityOptions to a specific provider since there is no named options. So we have strongly typed options // and strongly typed ILookupNormalizer and IdentityErrorDescriber since those are 'global' and we need to be unintrusive. // TODO: Could move all of this to BackOfficeComposer? // Services used by identity services.TryAddScoped, UserValidator>(); services.TryAddScoped, PasswordValidator>(); services.TryAddScoped>( services => new BackOfficePasswordHasher( new PasswordSecurity(services.GetRequiredService()), services.GetRequiredService())); services.TryAddScoped, DefaultUserConfirmation>(); services.TryAddScoped, UserClaimsPrincipalFactory>(); services.TryAddScoped>(); // CUSTOM: services.TryAddScoped(); services.TryAddScoped(); return new IdentityBuilder(typeof(BackOfficeIdentityUser), services); } } }