网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;

namespace Dpz.Core.Web.Library;

public class UserStore : IUserStore<VmUserInfo>
{
    private readonly IAccountService _accountService;

    public UserStore(IAccountService accountService)
    {
        _accountService = accountService;
    }

    public void Dispose() { }

    public async Task<string> GetUserIdAsync(VmUserInfo user, CancellationToken cancellationToken)
    {
        return await Task.Run(() => user.Id, cancellationToken);
    }

    public async Task<string?> GetUserNameAsync(
        VmUserInfo user,
        CancellationToken cancellationToken
    )
    {
        return await Task.Run(() => user.Name, cancellationToken);
    }

    public async Task SetUserNameAsync(
        VmUserInfo user,
        string? userName,
        CancellationToken cancellationToken
    )
    {
        await Task.Run(() => user.Name = userName, cancellationToken);
    }

    public async Task<string?> GetNormalizedUserNameAsync(
        VmUserInfo user,
        CancellationToken cancellationToken
    )
    {
        return await Task.Run(() => user.Name, cancellationToken);
    }

    public async Task SetNormalizedUserNameAsync(
        VmUserInfo user,
        string? normalizedName,
        CancellationToken cancellationToken
    )
    {
        await Task.Run(() => user.Name = normalizedName, cancellationToken);
    }

    public Task<IdentityResult> CreateAsync(VmUserInfo user, CancellationToken cancellationToken)
    {
        throw new System.NotImplementedException();
    }

    public Task<IdentityResult> UpdateAsync(VmUserInfo user, CancellationToken cancellationToken)
    {
        throw new System.NotImplementedException();
    }

    public Task<IdentityResult> DeleteAsync(VmUserInfo user, CancellationToken cancellationToken)
    {
        throw new System.NotImplementedException();
    }

    public async Task<VmUserInfo?> FindByIdAsync(string userId, CancellationToken cancellationToken)
    {
        return await _accountService.GetOneUserAsync(userId);
    }

    public async Task<VmUserInfo?> FindByNameAsync(
        string normalizedUserName,
        CancellationToken cancellationToken
    )
    {
        return await _accountService.GetUserInfoByNameAsync(normalizedUserName);
    }
}

public class UserInfoClaimsPrincipalFactory : IUserClaimsPrincipalFactory<VmUserInfo>
{
    public async Task<ClaimsPrincipal> CreateAsync(VmUserInfo user)
    {
        return await Task.Run(() =>
        {
            var claims = user.GetType()
                .GetProperties()
                .Select(x => new Claim(x.Name, x.GetValue(user)?.ToString() ?? ""))
                .ToList();
            claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id));
            var principal = new ClaimsPrincipal(
                new ClaimsIdentity(claims, Program.AuthorizeCookieName, "Name", "Permissions")
            );
            return principal;
        });
    }
}

public interface IApplicationSignInManager
{
    Task SignInAsync(
        VmUserInfo user,
        AuthenticationProperties authenticationProperties,
        string? authenticationMethod = null
    );

    Task<SignInResult> CheckPasswordSignInAsync(
        VmUserInfo user,
        string password,
        bool lockoutOnFailure
    );

    Task<SignInResult> PasswordSignInAsync(
        string userName,
        string password,
        bool isPersistent,
        bool lockoutOnFailure
    );

    Task RefreshSignInAsync(VmUserInfo user);

    bool IsSignedIn(ClaimsPrincipal principal);

    Task SignInWithClaimsAsync(
        VmUserInfo user,
        AuthenticationProperties authenticationProperties,
        IEnumerable<Claim> additionalClaims
    );
}

public class ApplicationSignInManager : SignInManager<VmUserInfo>, IApplicationSignInManager
{
    private readonly IAccountService _accountService;
    private readonly UserManager<VmUserInfo> _userManager;
    private readonly IAuthenticationSchemeProvider _schemes;
    private readonly IFusionCache _fusionCache;
    private readonly IHttpContextAccessor _contextAccessor;
    private readonly IUserClaimsPrincipalFactory<VmUserInfo> _claimsFactory;
    private readonly ILogger<ApplicationSignInManager> _logger;

    public ApplicationSignInManager(
        IAccountService accountService,
        UserManager<VmUserInfo> userManager,
        IHttpContextAccessor contextAccessor,
        IUserClaimsPrincipalFactory<VmUserInfo> claimsFactory,
        IOptions<IdentityOptions> optionsAccessor,
        ILogger<ApplicationSignInManager> logger,
        IAuthenticationSchemeProvider schemes,
        IUserConfirmation<VmUserInfo> userConfirmation,
        IFusionCache fusionCache
    )
        : base(
            userManager,
            contextAccessor,
            claimsFactory,
            optionsAccessor,
            logger,
            schemes,
            userConfirmation
        )
    {
        _accountService = accountService;
        _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager));
        _logger = logger;
        _schemes = schemes;
        _fusionCache = fusionCache;
        _contextAccessor = contextAccessor;
        _claimsFactory = claimsFactory;
    }

    public override async Task SignInAsync(
        VmUserInfo user,
        AuthenticationProperties authenticationProperties,
        string? authenticationMethod = null
    )
    {
        ClaimsPrincipal userPrincipalAsync = await base.CreateUserPrincipalAsync(user);
        if (authenticationMethod != null)
            userPrincipalAsync
                .Identities.First()
                .AddClaim(
                    new Claim(
                        "https://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod",
                        authenticationMethod
                    )
                );
        await Context.SignInAsync(
            Program.AuthorizeCookieName,
            userPrincipalAsync,
            authenticationProperties ?? new AuthenticationProperties()
        );
    }

    public override async Task<SignInResult> CheckPasswordSignInAsync(
        VmUserInfo user,
        string password,
        bool lockoutOnFailure
    )
    {
        var userInfo = await _accountService.LoginAsync(
            user.Id,
            (user.Id + password).GenerateMd5()
        );
        if (userInfo == null)
            return SignInResult.Failed;
        user = userInfo;
        return SignInResult.Success;
        //return base.CheckPasswordSignInAsync(user, password, lockoutOnFailure);
    }

    public override async Task<SignInResult> PasswordSignInAsync(
        string userName,
        string password,
        bool isPersistent,
        bool lockoutOnFailure
    )
    {
        var userInfo = await _accountService.LoginAsync(
            userName,
            (userName + password).GenerateMd5()
        );
        if (userInfo == null)
            return SignInResult.Failed;

        var result = await base.SignInOrTwoFactorAsync(userInfo, isPersistent, null, false);
        if (result.Succeeded)
        {
            await _fusionCache.SetAsync(
                _userInfoKey(userName),
                userInfo,
                TimeSpan.FromDays(14)
            );
        }

        return result;
    }

    private readonly Func<string, string> _userInfoKey = x => $"account-info-{x}";

    public override async Task RefreshSignInAsync(VmUserInfo user)
    {
        _logger.LogInformation("refresh sign");
        var authenticateResult = await Context.AuthenticateAsync(Program.AuthorizeCookieName);
        await Context.SignInAsync(
            Program.AuthorizeCookieName,
            await _claimsFactory.CreateAsync(user),
            authenticateResult?.Properties
        );
    }

    /// <summary>
    /// 判断应用程序cookie身份
    /// </summary>
    /// <param name="principal"></param>
    /// <returns></returns>
    public override bool IsSignedIn(ClaimsPrincipal principal)
    {
        _logger.LogInformation("IsSignedIn");
        if (principal == null)
        {
            throw new ArgumentNullException(nameof(principal));
        }

        return principal.Identities.Any(i => i.AuthenticationType == Program.AuthorizeCookieName);
    }

    /// <summary>
    /// 登录指定的用户 <see cref="VmUserInfo"/>
    /// </summary>
    /// <param name="user"></param>
    /// <param name="authenticationProperties"></param>
    /// <param name="additionalClaims"></param>
    /// <returns></returns>
    public override async Task SignInWithClaimsAsync(
        VmUserInfo user,
        AuthenticationProperties? authenticationProperties,
        IEnumerable<Claim> additionalClaims
    )
    {
        _logger.LogInformation("SignInWithClaimsAsync");
        var userPrincipal = await CreateUserPrincipalAsync(user);
        foreach (var claim in additionalClaims)
        {
            userPrincipal.Identities.First().AddClaim(claim);
        }

        await Context.SignInAsync(
            Program.AuthorizeCookieName,
            userPrincipal,
            authenticationProperties ?? new AuthenticationProperties()
        );
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码实现了一个用户身份验证和管理的系统,主要使用了 ASP.NET Core Identity 框架。以下是代码的主要组成部分及其功能的详细解释:

1. UserStore

UserStore 类实现了 IUserStore<VmUserInfo> 接口,负责用户的存储和管理。它使用一个 IAccountService 服务来与用户数据进行交互。主要功能包括:

  • 获取用户信息:通过 GetUserIdAsyncGetUserNameAsync 方法获取用户的 ID 和用户名。
  • 设置用户信息:通过 SetUserNameAsyncSetNormalizedUserNameAsync 方法设置用户的用户名。
  • 查找用户:通过 FindByIdAsyncFindByNameAsync 方法根据用户 ID 或用户名查找用户。
  • 创建、更新和删除用户:这些方法目前未实现(抛出 NotImplementedException),但它们的存在表明该类的设计是为了支持这些操作。

2. UserInfoClaimsPrincipalFactory

UserInfoClaimsPrincipalFactory 类实现了 IUserClaimsPrincipalFactory<VmUserInfo> 接口,负责创建用户的 ClaimsPrincipal 对象。ClaimsPrincipal 是一个表示用户的身份和声明的对象。主要功能包括:

  • 创建用户的 ClaimsPrincipal:通过 CreateAsync 方法,使用用户的属性生成一组声明,并将其封装在 ClaimsPrincipal 中。

3. IApplicationSignInManager 接口

IApplicationSignInManager 接口定义了一组用于用户登录和身份验证的方法,包括:

  • 用户登录SignInAsyncSignInWithClaimsAsync 方法用于登录用户。
  • 密码验证CheckPasswordSignInAsyncPasswordSignInAsync 方法用于验证用户的密码。
  • 刷新登录状态RefreshSignInAsync 方法用于刷新用户的登录状态。
  • 检查用户是否已登录IsSignedIn 方法用于检查用户的身份。

4. ApplicationSignInManager

ApplicationSignInManager 类继承自 SignInManager<VmUserInfo>,实现了 IApplicationSignInManager 接口,提供了用户登录的具体实现。主要功能包括:

  • 用户登录:重写 SignInAsyncPasswordSignInAsync 方法,使用 IAccountService 进行用户身份验证,并在成功后创建用户的 ClaimsPrincipal
  • 密码验证:重写 CheckPasswordSignInAsync 方法,使用 IAccountService 验证用户的密码。
  • 刷新登录状态:重写 RefreshSignInAsync 方法,更新用户的登录信息。
  • 检查用户身份:重写 IsSignedIn 方法,检查用户是否已登录。
  • 登录时附加声明SignInWithClaimsAsync 方法允许在登录时附加额外的声明。

总结

整体来看,这段代码实现了一个基于 ASP.NET Core Identity 的用户身份验证系统,提供了用户的存储、管理和身份验证功能。通过 UserStoreApplicationSignInManager 类,系统能够处理用户的登录、密码验证、用户信息管理等操作。UserInfoClaimsPrincipalFactory 则负责将用户信息转换为可用于身份验证的声明。

loading