如何为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类生效,你需要将其注册依赖注入系统中.
注册到依赖注入
应该使用 IdentityBuilder 的 IdentityBuilderExtensions 类的 AddSignInManager 扩展方法注册 CustomSignInManager
.
在你的 .Web
项目找到 YourProjectNameWebModule
的 PreConfigureServices
方法添加以下代码替换老的 SignInManager
:
PreConfigure<IdentityBuilder>(identityBuilder =>
{
identityBuilder.AddSignInManager<CustomSignInManager>();
});
本文的源代码
你可以在这里找到已完成的示例源码.