Files
mixtape/zero.Core/Identity/Security/SchemedSignInManager.cs
T
2021-12-03 14:45:49 +01:00

103 lines
3.1 KiB
C#

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Security.Claims;
namespace zero.Identity;
// TODO although the login per application works
// the authentication breaks when another application signs in a user
// they share one cookie on both sites/applications, maybe this is an issue
public class SchemedSignInManager<TUser> : SignInManager<TUser> where TUser : ZeroIdentityUser
{
protected ZeroAuthOptions<TUser> AuthOptions { get; private set; }
protected IZeroContext Zero { get; private set; }
public SchemedSignInManager(UserManager<TUser> userManager, IHttpContextAccessor contextAccessor, IUserClaimsPrincipalFactory<TUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor, ILogger<SignInManager<TUser>> logger, IAuthenticationSchemeProvider schemes, IUserConfirmation<TUser> confirmation, IOptions<ZeroAuthOptions<TUser>> authOptions,
IZeroContext zero)
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
{
AuthOptions = authOptions.Value;
Zero = zero;
}
/// <inheritdoc />
public override Task<bool> CanSignInAsync(TUser user)
{
if (!user.IsActive)
{
return Task.FromResult(false);
}
return base.CanSignInAsync(user);
}
/// <inheritdoc />
public override bool IsSignedIn(ClaimsPrincipal principal)
{
if (principal?.Identities == null)
{
return false;
}
if (!principal.Identities.Any(x => x.AuthenticationType == AuthOptions.Scheme))
{
return false;
}
string userAppId = principal.FindFirstValue(Constants.Auth.Claims.AppId);
return userAppId == null || Zero.AppId.Equals(userAppId, StringComparison.InvariantCultureIgnoreCase);
}
/// <inheritdoc />
public override async Task RefreshSignInAsync(TUser user)
{
var auth = await Context.AuthenticateAsync(AuthOptions.Scheme);
IList<Claim> claims = Array.Empty<Claim>();
var authenticationMethod = auth?.Principal?.FindFirst(ClaimTypes.AuthenticationMethod);
var amr = auth?.Principal?.FindFirst("amr");
if (authenticationMethod != null || amr != null)
{
claims = new List<Claim>();
if (authenticationMethod != null)
{
claims.Add(authenticationMethod);
}
if (amr != null)
{
claims.Add(amr);
}
}
await SignInWithClaimsAsync(user, auth?.Properties, claims);
}
/// <inheritdoc />
public override async Task SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable<Claim> additionalClaims)
{
var userPrincipal = await CreateUserPrincipalAsync(user);
foreach (var claim in additionalClaims)
{
userPrincipal.Identities.First().AddClaim(claim);
}
await Context.SignInAsync(AuthOptions.Scheme, userPrincipal, authenticationProperties ?? new AuthenticationProperties());
}
/// <inheritdoc />
public override async Task SignOutAsync()
{
await Context.SignOutAsync(AuthOptions.Scheme);
}
}