2020-05-21 15:43:33 +10:00
using Microsoft.AspNetCore.Identity ;
2020-05-15 15:21:15 +01:00
using Microsoft.Extensions.DependencyInjection ;
2020-05-18 08:21:34 +01:00
using Microsoft.Extensions.DependencyInjection.Extensions ;
2020-05-17 07:56:59 +01:00
using Umbraco.Core ;
2020-05-17 08:48:36 +01:00
using Umbraco.Core.BackOffice ;
2020-05-27 13:48:26 +10:00
using Umbraco.Core.Configuration ;
using Umbraco.Core.Security ;
using Umbraco.Core.Serialization ;
2020-05-17 07:56:59 +01:00
using Umbraco.Net ;
2020-05-21 15:43:33 +10:00
using Umbraco.Web.BackOffice.Security ;
2020-05-17 07:56:59 +01:00
using Umbraco.Web.Common.AspNetCore ;
2020-06-02 13:28:30 +10:00
using Umbraco.Web.Common.Security ;
2020-05-15 15:21:15 +01:00
namespace Umbraco.Extensions
{
public static class UmbracoBackOfficeServiceCollectionExtensions
{
2020-05-26 22:21:22 +10:00
/// <summary>
/// Adds the services required for running the Umbraco back office
/// </summary>
/// <param name="services"></param>
public static void AddUmbracoBackOffice ( this IServiceCollection services )
{
services . AddAntiforgery ( ) ;
2020-05-27 18:27:49 +10:00
services
. AddAuthentication ( Constants . Security . BackOfficeAuthenticationType )
. AddCookie ( Constants . Security . BackOfficeAuthenticationType ) ;
2020-06-02 13:28:30 +10:00
// TODO: Need to add more cookie options, see https://github.com/dotnet/aspnetcore/blob/3.0/src/Identity/Core/src/IdentityServiceCollectionExtensions.cs#L45
2020-05-27 18:27:49 +10:00
2020-06-02 13:28:30 +10:00
services . ConfigureOptions < ConfigureBackOfficeCookieOptions > ( ) ;
2020-05-26 22:21:22 +10:00
}
/// <summary>
/// Adds the services required for using Umbraco back office Identity
/// </summary>
/// <param name="services"></param>
2020-05-17 10:39:30 +01:00
public static void AddUmbracoBackOfficeIdentity ( this IServiceCollection services )
2020-05-15 15:21:15 +01:00
{
2020-05-18 08:21:34 +01:00
services . AddDataProtection ( ) ;
2020-05-18 13:00:32 +01:00
services . TryAddScoped < IIpResolver , AspNetCoreIpResolver > ( ) ;
2020-05-17 07:56:59 +01:00
2020-05-21 15:43:33 +10:00
services . BuildUmbracoBackOfficeIdentity ( )
2020-05-15 15:21:15 +01:00
. AddDefaultTokenProviders ( )
2020-05-17 07:56:59 +01:00
. AddUserStore < BackOfficeUserStore > ( )
2020-05-18 08:21:34 +01:00
. AddUserManager < BackOfficeUserManager > ( )
2020-05-27 13:48:26 +10:00
. AddSignInManager < BackOfficeSignInManager > ( )
2020-05-18 08:21:34 +01:00
. AddClaimsPrincipalFactory < BackOfficeClaimsPrincipalFactory < BackOfficeIdentityUser > > ( ) ;
2020-05-21 15:43:33 +10:00
// Configure the options specifically for the UmbracoBackOfficeIdentityOptions instance
2020-06-02 13:28:30 +10:00
services . ConfigureOptions < ConfigureBackOfficeIdentityOptions > ( ) ;
services . ConfigureOptions < ConfigureBackOfficeSecurityStampValidatorOptions > ( ) ;
2020-05-15 15:21:15 +01:00
}
2020-05-20 15:25:42 +10:00
2020-05-21 15:43:33 +10:00
private static IdentityBuilder BuildUmbracoBackOfficeIdentity ( this IServiceCollection services )
2020-05-20 15:25:42 +10:00
{
2020-05-21 15:43:33 +10:00
// 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.
2020-05-27 13:48:26 +10:00
// TODO: Could move all of this to BackOfficeComposer?
2020-05-21 15:43:33 +10:00
// Services used by identity
services . TryAddScoped < IUserValidator < BackOfficeIdentityUser > , UserValidator < BackOfficeIdentityUser > > ( ) ;
services . TryAddScoped < IPasswordValidator < BackOfficeIdentityUser > , PasswordValidator < BackOfficeIdentityUser > > ( ) ;
2020-05-27 13:48:26 +10:00
services . TryAddScoped < IPasswordHasher < BackOfficeIdentityUser > > (
services = > new BackOfficePasswordHasher (
2020-05-28 23:24:32 +10:00
new LegacyPasswordSecurity ( services . GetRequiredService < IUserPasswordConfiguration > ( ) ) ,
2020-05-27 13:48:26 +10:00
services . GetRequiredService < IJsonSerializer > ( ) ) ) ;
2020-05-21 15:43:33 +10:00
services . TryAddScoped < IUserConfirmation < BackOfficeIdentityUser > , DefaultUserConfirmation < BackOfficeIdentityUser > > ( ) ;
services . TryAddScoped < IUserClaimsPrincipalFactory < BackOfficeIdentityUser > , UserClaimsPrincipalFactory < BackOfficeIdentityUser > > ( ) ;
services . TryAddScoped < UserManager < BackOfficeIdentityUser > > ( ) ;
2020-05-27 13:48:26 +10:00
// CUSTOM:
2020-05-21 15:43:33 +10:00
services . TryAddScoped < BackOfficeLookupNormalizer > ( ) ;
services . TryAddScoped < BackOfficeIdentityErrorDescriber > ( ) ;
return new IdentityBuilder ( typeof ( BackOfficeIdentityUser ) , services ) ;
2020-05-20 15:25:42 +10:00
}
2020-05-15 15:21:15 +01:00
}
}