Creates IBackOfficeSignInManager interface
This commit is contained in:
@@ -14,11 +14,11 @@ namespace Umbraco.Tests.Integration.TestServerTest
|
||||
{
|
||||
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
private readonly BackOfficeSignInManager _backOfficeSignInManager;
|
||||
private readonly IBackOfficeSignInManager _backOfficeSignInManager;
|
||||
|
||||
private readonly BackOfficeIdentityUser _fakeUser;
|
||||
public TestAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, BackOfficeSignInManager backOfficeSignInManager, IUserService userService, UmbracoMapper umbracoMapper)
|
||||
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IBackOfficeSignInManager backOfficeSignInManager, IUserService userService, UmbracoMapper umbracoMapper)
|
||||
: base(options, logger, encoder, clock)
|
||||
{
|
||||
_backOfficeSignInManager = backOfficeSignInManager;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
{
|
||||
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
|
||||
private readonly IBackOfficeUserManager _userManager;
|
||||
private readonly BackOfficeSignInManager _signInManager;
|
||||
private readonly IBackOfficeSignInManager _signInManager;
|
||||
private readonly IUserService _userService;
|
||||
private readonly ILocalizedTextService _textService;
|
||||
private readonly UmbracoMapper _umbracoMapper;
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
public AuthenticationController(
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IBackOfficeUserManager backOfficeUserManager,
|
||||
BackOfficeSignInManager signInManager,
|
||||
IBackOfficeSignInManager signInManager,
|
||||
IUserService userService,
|
||||
ILocalizedTextService textService,
|
||||
UmbracoMapper umbracoMapper,
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
private readonly IGridConfig _gridConfig;
|
||||
private readonly BackOfficeServerVariables _backOfficeServerVariables;
|
||||
private readonly AppCaches _appCaches;
|
||||
private readonly BackOfficeSignInManager _signInManager;
|
||||
private readonly IBackOfficeSignInManager _signInManager;
|
||||
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
|
||||
private readonly ILogger<BackOfficeController> _logger;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
IGridConfig gridConfig,
|
||||
BackOfficeServerVariables backOfficeServerVariables,
|
||||
AppCaches appCaches,
|
||||
BackOfficeSignInManager signInManager,
|
||||
IBackOfficeSignInManager signInManager,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
ILogger<BackOfficeController> logger,
|
||||
IJsonSerializer jsonSerializer,
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Extensions
|
||||
.AddDefaultTokenProviders()
|
||||
.AddUserStore<BackOfficeUserStore>()
|
||||
.AddUserManager<IBackOfficeUserManager, BackOfficeUserManager>()
|
||||
.AddSignInManager<BackOfficeSignInManager>()
|
||||
.AddSignInManager<IBackOfficeSignInManager, BackOfficeSignInManager>()
|
||||
.AddClaimsPrincipalFactory<BackOfficeClaimsPrincipalFactory<BackOfficeIdentityUser>>();
|
||||
|
||||
// Configure the options specifically for the UmbracoBackOfficeIdentityOptions instance
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Extensions
|
||||
public static class IdentityBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a <see cref="UserManager{TUser}"/> for the <seealso cref="UserType"/>.
|
||||
/// Adds a <see cref="UserManager{TUser}"/> implementation for <seealso cref="BackOfficeIdentityUser"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="TUserManager">The type of the user manager to add.</typeparam>
|
||||
/// <typeparam name="TInterface"></typeparam>
|
||||
@@ -18,5 +18,19 @@ namespace Umbraco.Extensions
|
||||
identityBuilder.Services.AddScoped(typeof(TInterface), typeof(TUserManager));
|
||||
return identityBuilder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="SignInManager{TUser}"/> implementation for <seealso cref="BackOfficeIdentityUser"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="TInterface"></typeparam>
|
||||
/// <typeparam name="TSignInManager"></typeparam>
|
||||
/// <param name="identityBuilder"></param>
|
||||
/// <returns></returns>
|
||||
public static IdentityBuilder AddSignInManager<TInterface, TSignInManager>(this IdentityBuilder identityBuilder) where TSignInManager : SignInManager<BackOfficeIdentityUser>, TInterface
|
||||
{
|
||||
identityBuilder.AddSignInManager<TSignInManager>();
|
||||
identityBuilder.Services.AddScoped(typeof(TInterface), typeof(TSignInManager));
|
||||
return identityBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Web.BackOffice.Filters
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly ILocalizedTextService _localizedTextService;
|
||||
private readonly IOptions<GlobalSettings> _globalSettings;
|
||||
private readonly BackOfficeSignInManager _backOfficeSignInManager;
|
||||
private readonly IBackOfficeSignInManager _backOfficeSignInManager;
|
||||
private readonly IBackOfficeAntiforgery _backOfficeAntiforgery;
|
||||
|
||||
public CheckIfUserTicketDataIsStaleFilter(
|
||||
@@ -44,7 +44,7 @@ namespace Umbraco.Web.BackOffice.Filters
|
||||
IEntityService entityService,
|
||||
ILocalizedTextService localizedTextService,
|
||||
IOptions<GlobalSettings> globalSettings,
|
||||
BackOfficeSignInManager backOfficeSignInManager,
|
||||
IBackOfficeSignInManager backOfficeSignInManager,
|
||||
IBackOfficeAntiforgery backOfficeAntiforgery)
|
||||
{
|
||||
_requestCache = requestCache;
|
||||
|
||||
@@ -19,19 +19,17 @@ namespace Umbraco.Web.Common.Security
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
// TODO: There's potential to extract an interface for this for only what we use and put that in Core without aspnetcore refs, but we need to wait till were done with it since there's a bit to implement
|
||||
|
||||
public class BackOfficeSignInManager : SignInManager<BackOfficeIdentityUser>
|
||||
public class BackOfficeSignInManager : SignInManager<BackOfficeIdentityUser>, IBackOfficeSignInManager
|
||||
{
|
||||
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
|
||||
private const string UmbracoSignInMgrLoginProviderKey = "LoginProvider";
|
||||
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
|
||||
private const string UmbracoSignInMgrXsrfKey = "XsrfId";
|
||||
private const string UmbracoSignInMgrXsrfKey = "XsrfId";
|
||||
|
||||
private BackOfficeUserManager _userManager;
|
||||
private readonly IBackOfficeExternalLoginProviders _externalLogins;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
|
||||
|
||||
public BackOfficeSignInManager(
|
||||
BackOfficeUserManager userManager,
|
||||
@@ -75,7 +73,7 @@ namespace Umbraco.Web.Common.Security
|
||||
return await HandleSignIn(null, userName, SignInResult.Failed);
|
||||
return await PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<BackOfficeIdentityUser> GetTwoFactorAuthenticationUserAsync()
|
||||
{
|
||||
@@ -122,7 +120,7 @@ namespace Umbraco.Web.Common.Security
|
||||
return await HandleSignIn(user, user?.UserName, SignInResult.Failed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsSignedIn(ClaimsPrincipal principal)
|
||||
{
|
||||
@@ -204,7 +202,7 @@ namespace Umbraco.Web.Common.Security
|
||||
//await Context.SignOutAsync(Constants.Security.BackOfficeTwoFactorAuthenticationType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<bool> IsTwoFactorClientRememberedAsync(BackOfficeIdentityUser user)
|
||||
{
|
||||
@@ -216,7 +214,7 @@ namespace Umbraco.Web.Common.Security
|
||||
return (result?.Principal != null && result.Principal.FindFirstValue(ClaimTypes.Name) == userId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task RememberTwoFactorClientAsync(BackOfficeIdentityUser user)
|
||||
{
|
||||
@@ -229,7 +227,7 @@ namespace Umbraco.Web.Common.Security
|
||||
new AuthenticationProperties { IsPersistent = true });
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ForgetTwoFactorClientAsync()
|
||||
{
|
||||
@@ -239,7 +237,7 @@ namespace Umbraco.Web.Common.Security
|
||||
return Context.SignOutAsync(Constants.Security.BackOfficeTwoFactorRememberMeAuthenticationType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<SignInResult> TwoFactorRecoveryCodeSignInAsync(string recoveryCode)
|
||||
{
|
||||
@@ -268,7 +266,7 @@ namespace Umbraco.Web.Common.Security
|
||||
return SignInResult.Failed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
|
||||
{
|
||||
@@ -328,9 +326,9 @@ namespace Umbraco.Web.Common.Security
|
||||
if (user == null)
|
||||
{
|
||||
// user doesn't exist so see if we can auto link
|
||||
return await AutoLinkAndSignInExternalAccount(loginInfo, autoLinkOptions);
|
||||
return await AutoLinkAndSignInExternalAccount(loginInfo, autoLinkOptions);
|
||||
}
|
||||
|
||||
|
||||
if (autoLinkOptions != null && autoLinkOptions.OnExternalLogin != null)
|
||||
{
|
||||
var shouldSignIn = autoLinkOptions.OnExternalLogin(user, loginInfo);
|
||||
@@ -422,7 +420,7 @@ namespace Umbraco.Web.Common.Security
|
||||
if (username.IsNullOrWhiteSpace())
|
||||
{
|
||||
username = "UNKNOWN"; // could happen in 2fa or something else weird
|
||||
}
|
||||
}
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
@@ -432,14 +430,14 @@ namespace Umbraco.Web.Common.Security
|
||||
{
|
||||
//we have successfully logged in, reset the AccessFailedCount
|
||||
user.AccessFailedCount = 0;
|
||||
}
|
||||
}
|
||||
await UserManager.UpdateAsync(user);
|
||||
|
||||
Logger.LogInformation("User: {UserName} logged in from IP address {IpAddress}", username, Context.Connection.RemoteIpAddress);
|
||||
if (user != null)
|
||||
{
|
||||
_userManager.RaiseLoginSuccessEvent(user, user.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (result.IsLockedOut)
|
||||
{
|
||||
@@ -449,7 +447,7 @@ namespace Umbraco.Web.Common.Security
|
||||
else if (result.RequiresTwoFactor)
|
||||
{
|
||||
Logger.LogInformation("Login attempt requires verification for username {UserName} from IP address {IpAddress}", username, Context.Connection.RemoteIpAddress);
|
||||
}
|
||||
}
|
||||
else if (!result.Succeeded || result.IsNotAllowed)
|
||||
{
|
||||
Logger.LogInformation("Login attempt failed for username {UserName} from IP address {IpAddress}", username, Context.Connection.RemoteIpAddress);
|
||||
@@ -560,7 +558,7 @@ namespace Umbraco.Web.Common.Security
|
||||
if (autoLinkOptions == null || !autoLinkOptions.AutoLinkExternalAccount)
|
||||
{
|
||||
return SignInResult.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
var email = loginInfo.Principal.FindFirstValue(ClaimTypes.Email);
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Umbraco.Web.BackOffice.Security
|
||||
// We need to resolve the BackOfficeSecurityStampValidator per request as a requirement (even in aspnetcore they do this)
|
||||
var securityStampValidator = ctx.HttpContext.RequestServices.GetRequiredService<BackOfficeSecurityStampValidator>();
|
||||
// Same goes for the signinmanager
|
||||
var signInManager = ctx.HttpContext.RequestServices.GetRequiredService<BackOfficeSignInManager>();
|
||||
var signInManager = ctx.HttpContext.RequestServices.GetRequiredService<IBackOfficeSignInManager>();
|
||||
|
||||
var backOfficeIdentity = ctx.Principal.GetUmbracoIdentity();
|
||||
if (backOfficeIdentity == null)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.BackOffice;
|
||||
|
||||
namespace Umbraco.Web.Common.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="SignInManager{BackOfficeIdentityUser}"/> for the back office with a <seealso cref="BackOfficeIdentityUser"/>
|
||||
/// </summary>
|
||||
public interface IBackOfficeSignInManager
|
||||
{
|
||||
AuthenticationProperties ConfigureExternalAuthenticationProperties(string provider, string redirectUrl, string userId = null);
|
||||
Task<SignInResult> ExternalLoginSignInAsync(ExternalLoginInfo loginInfo, bool isPersistent, bool bypassTwoFactor = false);
|
||||
Task<IEnumerable<AuthenticationScheme>> GetExternalAuthenticationSchemesAsync();
|
||||
Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null);
|
||||
Task<BackOfficeIdentityUser> GetTwoFactorAuthenticationUserAsync();
|
||||
Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure);
|
||||
Task SignOutAsync();
|
||||
Task SignInAsync(BackOfficeIdentityUser user, bool isPersistent, string authenticationMethod = null);
|
||||
Task<ClaimsPrincipal> CreateUserPrincipalAsync(BackOfficeIdentityUser user);
|
||||
Task<SignInResult> TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
@using Umbraco.Extensions
|
||||
@using Umbraco.Core.Logging
|
||||
@using Umbraco.Web.BackOffice.Controllers
|
||||
@inject BackOfficeSignInManager SignInManager
|
||||
@inject IBackOfficeSignInManager SignInManager
|
||||
@inject BackOfficeServerVariables BackOfficeServerVariables
|
||||
@inject IUmbracoVersion UmbracoVersion
|
||||
@inject IHostingEnvironment HostingEnvironment
|
||||
|
||||
Reference in New Issue
Block a user