mirror of https://github.com/abpframework/abp
Merge pull request #3480 from gterdem/gterdem/how_to_update
How-to Documentation update and enhancementspull/3494/head
commit
8bc532531e
@ -1,84 +1,100 @@
|
||||
# Customize the SignInManager
|
||||
# How to Customize the SignIn Manager for ABP Applications
|
||||
|
||||
## Introduction
|
||||
After creating a new application using the [application startup template](../Startup-Templates/Application.md), you may want extend or change the default behavior of the SignIn Manager for your authentication and registration flow needs. ABP [Account Module](../Modules/Account.md) uses the [Identity Management Module](../Modules/Identity.md) for SignIn Manager and the [Identity Management Module](../Modules/Identity.md) uses default [Microsoft Identity SignIn Manager](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs) ([see here](https://github.com/abpframework/abp/blob/be32a55449e270d2d456df3dabdc91f3ffdd4fa9/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs#L17)).
|
||||
|
||||
ABP Framework uses Microsoft Identity underneath hence supports customization as much as Microsoft Identity does.
|
||||
To write your Custom SignIn Manager, you need to extend [Microsoft Identity SignIn Manager](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs) class and register it to the DI container.
|
||||
|
||||
## Sample Code
|
||||
This document explains how to customize the SignIn Manager for your own application.
|
||||
|
||||
https://github.com/abpframework/abp-samples/blob/master/aspnet-core/BookStore-AzureAD/src/Acme.BookStore.Web/CustomSignInManager.cs
|
||||
## Create a CustomSignInManager
|
||||
|
||||
## Creating CustomSignInManager
|
||||
Create a new class inheriting the [SignInMager](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs) of Microsoft Identity package.
|
||||
|
||||
To create your own custom SignIn Manager, you need to inherit `SignInManager<Volo.Abp.Identity.IdentityUser>`.
|
||||
|
||||
````xml
|
||||
public class CustomSignInManager : SignInManager<Volo.Abp.Identity.IdentityUser>
|
||||
````csharp
|
||||
public class CustomSignInManager : Microsoft.AspNetCore.Identity.SignInManager<Volo.Abp.Identity.IdentityUser>
|
||||
{
|
||||
public CustomSigninManager(
|
||||
UserManager<Volo.Abp.Identity.IdentityUser> userManager,
|
||||
IHttpContextAccessor contextAccessor,
|
||||
IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser> claimsFactory,
|
||||
IOptions<IdentityOptions> optionsAccessor,
|
||||
ILogger<SignInManager<Volo.Abp.Identity.IdentityUser>> logger,
|
||||
IAuthenticationSchemeProvider schemes,
|
||||
IUserConfirmation<Volo.Abp.Identity.IdentityUser> confirmation)
|
||||
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
|
||||
{
|
||||
}
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
> It is important to use **Volo.Abp.Identity.IdentityUser** type for SignInManager to inherit, not the AppUser of your application.
|
||||
|
||||
Afterwards you can override any of the SignIn Manager methods you need and add new methods and properties needed for your authentication or registration flow.
|
||||
|
||||
## Overriding the GetExternalLoginInfoAsync Method
|
||||
|
||||
## Overriding Methods
|
||||
In this case we'll be overriding the `GetExternalLoginInfoAsync` method which is invoked when a third party authentication is implemented.
|
||||
|
||||
Afterwards you can override a method like `GetExternalLoginInfoAsync`:
|
||||
A good way to override a method is copying its [source code](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Identity/Core/src/SignInManager.cs#L638-L674). In this case, we will be using a minorly modified version of the source code which explicitly shows the namespaces of the methods and properties to help better understanding of the concept.
|
||||
|
||||
````xml
|
||||
public override async Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
|
||||
````csharp
|
||||
public override async Task<Microsoft.AspNetCore.Identity.ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
|
||||
{
|
||||
var auth = await Context.AuthenticateAsync(IdentityConstants.ExternalScheme);
|
||||
var auth = await Context.AuthenticateAsync(Microsoft.AspNetCore.Identity.IdentityConstants.ExternalScheme);
|
||||
var items = auth?.Properties?.Items;
|
||||
if (auth?.Principal == null || items == null || !items.ContainsKey("LoginProvider"))
|
||||
if (auth?.Principal == null || items == null || !items.ContainsKey("LoginProviderKey"))
|
||||
{
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expectedXsrf != null)
|
||||
{
|
||||
if (!items.ContainsKey("XsrfId"))
|
||||
if (!items.ContainsKey("XsrfKey"))
|
||||
{
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
var userId = items[XsrfKey] as string;
|
||||
if (userId != expectedXsrf)
|
||||
{
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var providerKey = auth.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var provider = items[LoginProviderKey] as string;
|
||||
if (providerKey == null || provider == null)
|
||||
{
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
var providerDisplayName = (await GetExternalAuthenticationSchemesAsync()).FirstOrDefault(p => p.Name == provider)?.DisplayName ?? provider;
|
||||
return new ExternalLoginInfo(auth.Principal, provider, providerKey, providerDisplayName)
|
||||
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()
|
||||
AuthenticationTokens = auth.Properties.GetTokens()
|
||||
};
|
||||
}
|
||||
````
|
||||
|
||||
To get your overridden method invoked and your customized SignIn Manager class to work, you need to register your class to the [Dependency Injection System](../Dependency-Injection.md).
|
||||
|
||||
## Register to Dependency Injection
|
||||
|
||||
## Registering to DI
|
||||
Registering `CustomSignInManager` should be done with adding **AddSignInManager** extension method of the [IdentityBuilderExtensions](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/IdentityBuilderExtensions.cs) of the [IdentityBuilder](https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Extensions.Core/src/IdentityBuilder.cs).
|
||||
|
||||
You need to register your Custom SignIn Manager to DI to activate it. Inside the `.Web` project, locate the `ApplicationNameWebModule` and add the following under `ConfigureServices` method:
|
||||
Inside your `.Web` project, locate the `ApplicationNameWebModule` and add the following under `ConfigureServices` method to replace the old SignInManager with your customized one.
|
||||
|
||||
````xml
|
||||
````csharp
|
||||
context.Services
|
||||
.GetObject<IdentityBuilder>()
|
||||
.AddSignInManager<CustomSigninManager>();
|
||||
````
|
||||
.AddSignInManager<CustomSignInManager>();
|
||||
````
|
||||
|
||||
## The Source Code
|
||||
|
||||
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization).
|
||||
|
||||
## See Also
|
||||
|
||||
* [How to Customize the Login Page for MVC / Razor Page Applications](Customize-Login-Page-MVC.md).
|
||||
* [Identity Management Module](../Modules/Identity.md).
|
||||
Loading…
Reference in new issue