Merge branch 'v14/dev' into v15/dev
# Conflicts: # src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs # src/Umbraco.Web.Common/Views/UmbracoViewPage.cs
This commit is contained in:
@@ -62,9 +62,16 @@ public static class HttpContextExtensions
|
||||
// Update the HttpContext's user with the authenticated user's principal to ensure
|
||||
// that subsequent requests within the same context will recognize the user
|
||||
// as authenticated.
|
||||
if (result.Succeeded)
|
||||
if (result is { Succeeded: true, Principal.Identity: not null })
|
||||
{
|
||||
httpContext.User = result.Principal;
|
||||
// We need to get existing identities that are not the backoffice kind and flow them to the new identity
|
||||
// Otherwise we can't log in as both a member and a backoffice user
|
||||
// For instance if you've enabled basic auth.
|
||||
ClaimsPrincipal? authenticatedPrincipal = result.Principal;
|
||||
IEnumerable<ClaimsIdentity> existingIdentities = httpContext.User.Identities.Where(x => x.IsAuthenticated && x.AuthenticationType != authenticatedPrincipal.Identity.AuthenticationType);
|
||||
authenticatedPrincipal.AddIdentities(existingIdentities);
|
||||
|
||||
httpContext.User = authenticatedPrincipal;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Umbraco.Extensions;
|
||||
|
||||
public static class MemberClaimsPrincipalExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to get specifically the member identity from the ClaimsPrincipal
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The identity returned is the one with default authentication type.
|
||||
/// </remarks>
|
||||
/// <param name="principal">The principal to find the identity in.</param>
|
||||
/// <returns>The default authenticated authentication type identity.</returns>
|
||||
public static ClaimsIdentity? GetMemberIdentity(this ClaimsPrincipal principal)
|
||||
=> principal.Identities.FirstOrDefault(x => x.AuthenticationType == IdentityConstants.ApplicationScheme);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public sealed class ConfigureMemberIdentityOptions : IConfigureOptions<IdentityO
|
||||
options.SignIn.RequireConfirmedEmail = false; // not implemented
|
||||
options.SignIn.RequireConfirmedPhoneNumber = false; // not implemented
|
||||
|
||||
options.User.RequireUniqueEmail = true;
|
||||
options.User.RequireUniqueEmail = _securitySettings.MemberRequireUniqueEmail;
|
||||
|
||||
// Support validation of member names using Down-Level Logon Name format
|
||||
options.User.AllowedUserNameCharacters = _securitySettings.AllowedUserNameCharacters;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -113,8 +114,11 @@ public class MemberManager : UmbracoUserManager<MemberIdentityUser, MemberPasswo
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsLoggedIn()
|
||||
{
|
||||
HttpContext? httpContext = _httpContextAccessor.HttpContext;
|
||||
return httpContext?.User.Identity?.IsAuthenticated ?? false;
|
||||
// We have to try and specifically find the member identity, it's entirely possible for there to be both backoffice and member.
|
||||
ClaimsIdentity? memberIdentity = _httpContextAccessor.HttpContext?.User.GetMemberIdentity();
|
||||
|
||||
return memberIdentity is not null &&
|
||||
memberIdentity.IsAuthenticated;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -170,23 +174,27 @@ public class MemberManager : UmbracoUserManager<MemberIdentityUser, MemberPasswo
|
||||
/// <inheritdoc />
|
||||
public virtual async Task<MemberIdentityUser?> GetCurrentMemberAsync()
|
||||
{
|
||||
if (_currentMember == null)
|
||||
if (_currentMember is not null)
|
||||
{
|
||||
if (!IsLoggedIn())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_currentMember = await GetUserAsync(_httpContextAccessor.HttpContext?.User!);
|
||||
return _currentMember;
|
||||
}
|
||||
|
||||
if (IsLoggedIn() is false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a principal the represents the member security context.
|
||||
var memberPrincipal = new ClaimsPrincipal(_httpContextAccessor.HttpContext?.User.GetMemberIdentity()!);
|
||||
_currentMember = await GetUserAsync(memberPrincipal);
|
||||
|
||||
return _currentMember;
|
||||
}
|
||||
|
||||
public virtual IPublishedContent? AsPublishedMember(MemberIdentityUser user) => _store.GetPublishedMember(user);
|
||||
|
||||
/// <summary>
|
||||
/// This will check if the member has access to this path
|
||||
/// This will check if the member has access to this path.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
Reference in New Issue
Block a user