You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
abp/docs/zh-Hans/How-To/Customize-SignIn-Manager.md

5.2 KiB

如何为ABP应用程序定制SignIn Manager

在使用应用程序启动模板创建新项目后,你可能想要扩展或更改SignIn Manager的默认行为,以满足你需要的身份验证和注册流程. ABP账户模块使用身份管理模块做为SignIn Manager,而身份管理模块使用默认的Microsoft Identity SignIn Manager(参阅此处).

编写自定义SignIn Manager,你需要扩展Microsoft Identity SignIn Manager类并注入到DI容器.

本文介绍了如何为你自己的应用程序自定义SignIn Manager.

创建 CustomSignInManager

创建一个类并继承自Microsoft Identity 包的 SignInMager.

public class CustomSignInManager : Microsoft.AspNetCore.Identity.SignInManager<Volo.Abp.Identity.IdentityUser>
{
        public CustomSignInManager(
            Microsoft.AspNetCore.Identity.UserManager<Volo.Abp.Identity.IdentityUser> userManager,
            Microsoft.AspNetCore.Http.IHttpContextAccessor contextAccessor,
            Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser> claimsFactory,
            Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.IdentityOptions> optionsAccessor,
            Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.Identity.SignInManager<Volo.Abp.Identity.IdentityUser>> logger,
            Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider schemes,
            Microsoft.AspNetCore.Identity.IUserConfirmation<Volo.Abp.Identity.IdentityUser> confirmation)
            : base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
        {
        }
}

重点是使用Volo.Abp.Identity.IdentityUser做为泛型参数,而不是应用程序的AppUser.

然后你可以覆盖SignIn Manager的任何方法并且为你的身份验证和注册流程添加需要的方法和属性.

重写 GetExternalLoginInfoAsync 方法

在这个用例中我们重写第三方身份验证时使用的 GetExternalLoginInfoAsync 方法实现.

一个好的开始是从复制源码而不是从零开始. 在这个用例中我们对源码进行较少的修改,为了帮助理解概念它显式显示了方法和属性的命名空间.

public override async Task<Microsoft.AspNetCore.Identity.ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
{
    var auth = await Context.AuthenticateAsync(Microsoft.AspNetCore.Identity.IdentityConstants.ExternalScheme);
    var items = auth?.Properties?.Items;
    if (auth?.Principal == null || items == null || !items.ContainsKey("LoginProviderKey"))
    {
        return null;
    }

    if (expectedXsrf != null)
    {
        if (!items.ContainsKey("XsrfKey"))
        {
            return null;
        }
        var userId = items[XsrfKey] as string;
        if (userId != expectedXsrf)
        {
            return null;
        }
    }

    var providerKey = auth.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
    var provider = items[LoginProviderKey] as string;
    if (providerKey == null || provider == null)
    {
        return null;
    }

    var providerDisplayName = (await GetExternalAuthenticationSchemesAsync()).FirstOrDefault(p => p.Name == provider)?.DisplayName
        ?? provider;
    return new Microsoft.AspNetCore.Identity.ExternalLoginInfo(auth.Principal, provider, providerKey, providerDisplayName)
    {
        AuthenticationTokens = auth.Properties.GetTokens()
    };
}

要使你自定义的SignIn Manager类生效,你需要将其注册依赖注入系统中.

注册到依赖注入

应该使用 IdentityBuilderIdentityBuilderExtensions 类的 AddSignInManager 扩展方法注册 CustomSignInManager.

在你的 .Web 项目找到 YourProjectNameWebModulePreConfigureServices 方法添加以下代码替换老的 SignInManager:

PreConfigure<IdentityBuilder>(identityBuilder =>
{
    identityBuilder.AddSignInManager<CustomSignInManager>();
});

本文的源代码

你可以在这里找到已完成的示例源码.

另请参阅