Add settings to bypass 2fa for external logins (#11959)
* Added settings for bypassing 2fa for external logins * Fixed issue with saving roles using member ID before the member had an ID. * Added missing extension method * Removed test classes from git * rollback csproj
This commit is contained in:
@@ -11,6 +11,8 @@ namespace Umbraco.Cms.Core.Configuration.Models
|
|||||||
[UmbracoOptions(Constants.Configuration.ConfigSecurity)]
|
[UmbracoOptions(Constants.Configuration.ConfigSecurity)]
|
||||||
public class SecuritySettings
|
public class SecuritySettings
|
||||||
{
|
{
|
||||||
|
internal const bool StaticMemberBypassTwoFactorForExternalLogins = true;
|
||||||
|
internal const bool StaticUserBypassTwoFactorForExternalLogins = true;
|
||||||
internal const bool StaticKeepUserLoggedIn = false;
|
internal const bool StaticKeepUserLoggedIn = false;
|
||||||
internal const bool StaticHideDisabledUsersInBackOffice = false;
|
internal const bool StaticHideDisabledUsersInBackOffice = false;
|
||||||
internal const bool StaticAllowPasswordReset = true;
|
internal const bool StaticAllowPasswordReset = true;
|
||||||
@@ -66,5 +68,17 @@ namespace Umbraco.Cms.Core.Configuration.Models
|
|||||||
/// Gets or sets a value for the member password settings.
|
/// Gets or sets a value for the member password settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MemberPasswordConfigurationSettings MemberPassword { get; set; }
|
public MemberPasswordConfigurationSettings MemberPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to bypass the two factor requirement in Umbraco when using external login for members. Thereby rely on the External login and potential 2FA at that provider.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(StaticMemberBypassTwoFactorForExternalLogins)]
|
||||||
|
public bool MemberBypassTwoFactorForExternalLogins { get; set; } = StaticMemberBypassTwoFactorForExternalLogins;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to bypass the two factor requirement in Umbraco when using external login for users. Thereby rely on the External login and potential 2FA at that provider.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(StaticUserBypassTwoFactorForExternalLogins)]
|
||||||
|
public bool UserBypassTwoFactorForExternalLogins { get; set; } = StaticUserBypassTwoFactorForExternalLogins;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ namespace Umbraco.Cms.Core.Security
|
|||||||
// create the member
|
// create the member
|
||||||
_memberService.Save(memberEntity);
|
_memberService.Save(memberEntity);
|
||||||
|
|
||||||
|
//We need to add roles now that the member has an Id. It do not work implicit in UpdateMemberProperties
|
||||||
|
_memberService.AssignRoles(new[] { memberEntity.Id }, user.Roles.Select(x => x.RoleId).ToArray());
|
||||||
|
|
||||||
if (!memberEntity.HasIdentity)
|
if (!memberEntity.HasIdentity)
|
||||||
{
|
{
|
||||||
throw new DataException("Could not create the member, check logs for details");
|
throw new DataException("Could not create the member, check logs for details");
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Umbraco.Cms.Core;
|
using Umbraco.Cms.Core;
|
||||||
@@ -31,6 +32,7 @@ using Umbraco.Cms.Web.Common.ActionsResults;
|
|||||||
using Umbraco.Cms.Web.Common.Attributes;
|
using Umbraco.Cms.Web.Common.Attributes;
|
||||||
using Umbraco.Cms.Web.Common.Authorization;
|
using Umbraco.Cms.Web.Common.Authorization;
|
||||||
using Umbraco.Cms.Web.Common.Controllers;
|
using Umbraco.Cms.Web.Common.Controllers;
|
||||||
|
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||||
using Umbraco.Cms.Web.Common.Filters;
|
using Umbraco.Cms.Web.Common.Filters;
|
||||||
using Umbraco.Extensions;
|
using Umbraco.Extensions;
|
||||||
using Constants = Umbraco.Cms.Core.Constants;
|
using Constants = Umbraco.Cms.Core.Constants;
|
||||||
@@ -68,7 +70,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
|||||||
private readonly IBackOfficeTwoFactorOptions _backOfficeTwoFactorOptions;
|
private readonly IBackOfficeTwoFactorOptions _backOfficeTwoFactorOptions;
|
||||||
private readonly IManifestParser _manifestParser;
|
private readonly IManifestParser _manifestParser;
|
||||||
private readonly ServerVariablesParser _serverVariables;
|
private readonly ServerVariablesParser _serverVariables;
|
||||||
|
private readonly IOptions<SecuritySettings> _securitySettings;
|
||||||
|
|
||||||
|
|
||||||
|
[ActivatorUtilitiesConstructor]
|
||||||
public BackOfficeController(
|
public BackOfficeController(
|
||||||
IBackOfficeUserManager userManager,
|
IBackOfficeUserManager userManager,
|
||||||
IRuntimeState runtimeState,
|
IRuntimeState runtimeState,
|
||||||
@@ -87,7 +92,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
|||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions,
|
IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions,
|
||||||
IManifestParser manifestParser,
|
IManifestParser manifestParser,
|
||||||
ServerVariablesParser serverVariables)
|
ServerVariablesParser serverVariables,
|
||||||
|
IOptions<SecuritySettings> securitySettings)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_runtimeState = runtimeState;
|
_runtimeState = runtimeState;
|
||||||
@@ -107,6 +113,51 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
|||||||
_backOfficeTwoFactorOptions = backOfficeTwoFactorOptions;
|
_backOfficeTwoFactorOptions = backOfficeTwoFactorOptions;
|
||||||
_manifestParser = manifestParser;
|
_manifestParser = manifestParser;
|
||||||
_serverVariables = serverVariables;
|
_serverVariables = serverVariables;
|
||||||
|
_securitySettings = securitySettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use ctor with all params. This overload will be removed in Umbraco 10.")]
|
||||||
|
public BackOfficeController(
|
||||||
|
IBackOfficeUserManager userManager,
|
||||||
|
IRuntimeState runtimeState,
|
||||||
|
IRuntimeMinifier runtimeMinifier,
|
||||||
|
IOptions<GlobalSettings> globalSettings,
|
||||||
|
IHostingEnvironment hostingEnvironment,
|
||||||
|
ILocalizedTextService textService,
|
||||||
|
IGridConfig gridConfig,
|
||||||
|
BackOfficeServerVariables backOfficeServerVariables,
|
||||||
|
AppCaches appCaches,
|
||||||
|
IBackOfficeSignInManager signInManager,
|
||||||
|
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||||
|
ILogger<BackOfficeController> logger,
|
||||||
|
IJsonSerializer jsonSerializer,
|
||||||
|
IBackOfficeExternalLoginProviders externalLogins,
|
||||||
|
IHttpContextAccessor httpContextAccessor,
|
||||||
|
IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions,
|
||||||
|
IManifestParser manifestParser,
|
||||||
|
ServerVariablesParser serverVariables)
|
||||||
|
: this(userManager,
|
||||||
|
runtimeState,
|
||||||
|
runtimeMinifier,
|
||||||
|
globalSettings,
|
||||||
|
hostingEnvironment,
|
||||||
|
textService,
|
||||||
|
gridConfig,
|
||||||
|
backOfficeServerVariables,
|
||||||
|
appCaches,
|
||||||
|
signInManager,
|
||||||
|
backofficeSecurityAccessor,
|
||||||
|
logger,
|
||||||
|
jsonSerializer,
|
||||||
|
externalLogins,
|
||||||
|
httpContextAccessor,
|
||||||
|
backOfficeTwoFactorOptions,
|
||||||
|
manifestParser,
|
||||||
|
serverVariables,
|
||||||
|
StaticServiceProvider.Instance.GetRequiredService<IOptions<SecuritySettings>>()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -458,7 +509,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
|||||||
if (response == null) throw new ArgumentNullException(nameof(response));
|
if (response == null) throw new ArgumentNullException(nameof(response));
|
||||||
|
|
||||||
// Sign in the user with this external login provider (which auto links, etc...)
|
// Sign in the user with this external login provider (which auto links, etc...)
|
||||||
SignInResult result = await _signInManager.ExternalLoginSignInAsync(loginInfo, isPersistent: false);
|
SignInResult result = await _signInManager.ExternalLoginSignInAsync(loginInfo, isPersistent: false, bypassTwoFactor: _securitySettings.Value.UserBypassTwoFactorForExternalLogins);
|
||||||
|
|
||||||
var errors = new List<string>();
|
var errors = new List<string>();
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Umbraco.Cms.Core.Net;
|
|||||||
using Umbraco.Cms.Core.Scoping;
|
using Umbraco.Cms.Core.Scoping;
|
||||||
using Umbraco.Cms.Core.Security;
|
using Umbraco.Cms.Core.Security;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Infrastructure.Security;
|
||||||
using Umbraco.Cms.Web.BackOffice.Security;
|
using Umbraco.Cms.Web.BackOffice.Security;
|
||||||
using Umbraco.Cms.Web.Common.AspNetCore;
|
using Umbraco.Cms.Web.Common.AspNetCore;
|
||||||
using Umbraco.Cms.Web.Common.Security;
|
using Umbraco.Cms.Web.Common.Security;
|
||||||
@@ -77,5 +78,14 @@ namespace Umbraco.Extensions
|
|||||||
return umbracoBuilder;
|
return umbracoBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BackOfficeIdentityBuilder AddTwoFactorProvider<T>(this BackOfficeIdentityBuilder identityBuilder, string providerName) where T : class, ITwoFactorProvider
|
||||||
|
{
|
||||||
|
identityBuilder.Services.AddSingleton<ITwoFactorProvider, T>();
|
||||||
|
identityBuilder.Services.AddSingleton<T>();
|
||||||
|
identityBuilder.AddTokenProvider<TwoFactorBackOfficeValidationProvider<T>>(providerName);
|
||||||
|
|
||||||
|
return identityBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
<ProjectReference Include="../Umbraco.Web.Website/Umbraco.Web.Website.csproj" />
|
<ProjectReference Include="../Umbraco.Web.Website/Umbraco.Web.Website.csproj" />
|
||||||
<ProjectReference Include="../Umbraco.Persistence.SqlCe/Umbraco.Persistence.SqlCe.csproj" Condition="'$(OS)' == 'Windows_NT'" />
|
<ProjectReference Include="../Umbraco.Persistence.SqlCe/Umbraco.Persistence.SqlCe.csproj" Condition="'$(OS)' == 'Windows_NT'" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="App_Plugins" />
|
<Folder Include="App_Plugins" />
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ using Microsoft.AspNetCore.Http.Extensions;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Umbraco.Cms.Core.Cache;
|
using Umbraco.Cms.Core.Cache;
|
||||||
|
using Umbraco.Cms.Core.Configuration.Models;
|
||||||
using Umbraco.Cms.Core.Logging;
|
using Umbraco.Cms.Core.Logging;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Routing;
|
using Umbraco.Cms.Core.Routing;
|
||||||
@@ -29,6 +31,7 @@ namespace Umbraco.Cms.Web.Website.Controllers
|
|||||||
{
|
{
|
||||||
private readonly IMemberManager _memberManager;
|
private readonly IMemberManager _memberManager;
|
||||||
private readonly ITwoFactorLoginService _twoFactorLoginService;
|
private readonly ITwoFactorLoginService _twoFactorLoginService;
|
||||||
|
private readonly IOptions<SecuritySettings> _securitySettings;
|
||||||
private readonly ILogger<UmbExternalLoginController> _logger;
|
private readonly ILogger<UmbExternalLoginController> _logger;
|
||||||
private readonly IMemberSignInManagerExternalLogins _memberSignInManager;
|
private readonly IMemberSignInManagerExternalLogins _memberSignInManager;
|
||||||
|
|
||||||
@@ -42,7 +45,8 @@ namespace Umbraco.Cms.Web.Website.Controllers
|
|||||||
IPublishedUrlProvider publishedUrlProvider,
|
IPublishedUrlProvider publishedUrlProvider,
|
||||||
IMemberSignInManagerExternalLogins memberSignInManager,
|
IMemberSignInManagerExternalLogins memberSignInManager,
|
||||||
IMemberManager memberManager,
|
IMemberManager memberManager,
|
||||||
ITwoFactorLoginService twoFactorLoginService)
|
ITwoFactorLoginService twoFactorLoginService,
|
||||||
|
IOptions<SecuritySettings> securitySettings)
|
||||||
: base(
|
: base(
|
||||||
umbracoContextAccessor,
|
umbracoContextAccessor,
|
||||||
databaseFactory,
|
databaseFactory,
|
||||||
@@ -55,6 +59,7 @@ namespace Umbraco.Cms.Web.Website.Controllers
|
|||||||
_memberSignInManager = memberSignInManager;
|
_memberSignInManager = memberSignInManager;
|
||||||
_memberManager = memberManager;
|
_memberManager = memberManager;
|
||||||
_twoFactorLoginService = twoFactorLoginService;
|
_twoFactorLoginService = twoFactorLoginService;
|
||||||
|
_securitySettings = securitySettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -95,7 +100,7 @@ namespace Umbraco.Cms.Web.Website.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SignInResult result = await _memberSignInManager.ExternalLoginSignInAsync(loginInfo, false);
|
SignInResult result = await _memberSignInManager.ExternalLoginSignInAsync(loginInfo, false, _securitySettings.Value.MemberBypassTwoFactorForExternalLogins);
|
||||||
|
|
||||||
if (result == SignInResult.Success)
|
if (result == SignInResult.Success)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user