Open Source Web Application Framework for ASP.NET Core
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.
 
 
 
 
 
 

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>();
});

本文的源代码

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

另请参阅