Author : MD TAREQ HASSAN | Updated : 2020/05/28
Whais ASP.NeCore Identity?
- ASP.NECore Identity is a membership system which allows you to add functionalities (login, authentication, authorization etc.) to your application
- Users can create an accounand login with a user name and password or they can use an external login providers such as Facebook, Google, MicrosofAccount, Twitter and more
- ASP.NET Core Identity provides a framework for managing and storing user accounts in ASP.NET Core apps
- ASP.NECore Identity:
- Is an API thasupports user interface (UI) login functionality
- Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more
- Identity is a framework for authentication, authorization and user management (Note: authentication is handled by authentication middleware)
- In addition to authentication and authorization, Identity providers:
- registering new users
- password hashing
- user and password validation
- password reseand email confirmation
- MFA ( multi-factor authentication)
- authentication using external providers
- and so on
- Identity Classes & UI are provided as pre-compiled library (Identity related UI as Razor Page Library)
Notes:
- ASP.NeCore Identity is based on Kerberos
- Kerberos is a computer-network authentication protocol that works on the basis of tickets to allow nodes communicating over a non-secure network to prove their identity to one another in a secure manner
Identity helper functionalities
Resources
Structure and Architecture
public UserManager(IUserStore<TUser> store,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<TUser> passwordHasher,
IEnumerable<IUserValidator<TUser>> userValidators,
IEnumerable<IPasswordValidator<TUser>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<UserManager<TUser>> logger)
{
// ... ... ...
}
public RoleManager(IRoleStore<TRole> store,
IEnumerable<IRoleValidator<TRole>> roleValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
ILogger<RoleManager<TRole>> logger)
{
// ... ... ...
}
IUserStore<TUser>
interface
Task<IdentityResult> CreateAsync(TUser user, CancellationToken token);
Task<IdentityResult> UpdateAsync(TUser user, CancellationToken token);
Task<IdentityResult> DeleteAsync(TUser user, CancellationToken token);
Task<TUser> FindByIdAsync(string userId, CancellationToken token);
Task<TUser> FindByNameAsync(string normalizedUserName, CancellationToken token);
Task<string> GetUserIdAsync(TUser user, CancellationToken token);
Task<string> GetUserNameAsync(TUser user, CancellationToken token);
Task SetUserNameAsync(TUser user, string userName, CancellationToken token);
Task<string> GetNormalizedUserNameAsync(TUser user, CancellationToken token);
Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken token)
IUserStore sub-interfaces
IUserPasswordStore
: Password hashesIUserEmailStore
: Emails & confirmationIUserPhoneNumberStore
: Phone & confirmationIUserRoleStore
: Links users & rolesIUserClaimStore
: Additional claims for users (freeform)IUserLockoutStore
: Lockoufunctionality (e.g. failed attempts)IUserSecurityStampStore
: Security stampsIQueryableUserStore
: IQueryable access to underlying databaseIUserLoginStore
: External logins (think social)IUserAuthenticationTokenStore
: Storage of tokens from external loginsIUserAuthenticatorKeyStore
: e.g. Google AuthenticatorIUserTwoFactorStore
: Multi-Factor Authentication (MFA)IUserTwoFactorRecoveryCodeStore
: MFA recovery
We can extend any of these stores and add properties/methods if we need
Identity model
The Identity model consists of the following entity types
Entity type | Description |
---|---|
User | Represents the user |
Role | Represents a role |
UserClaim | Represents a claim that a user possesses |
UserToken | Represents an authentication token for a user |
UserLogin | Associates a user with a login |
RoleClaim | Represents a claim that’s granted to all users within a role |
UserRole | A join entity that associates users and roles |
See:
ASP.Net core identity defines default Common Language Runtime (CLR) types for each of the entity types listed above. These types are all prefixed with Identity:
IdentityUser
IdentityRole
IdentityUserClaim
IdentityUserToken
IdentityUserLogin
IdentityRoleClaim
IdentityUserRole
Identity Packages
Microsoft.AspNetCore.Identity
- Contains identity related entities (
IdentityUser
,IdentityRole
etc.) - Contains
UserManager<TUser>
,SignInManager<TUser>
etc.
- Contains identity related entities (
Microsoft.AspNetCore.Identity.EntityFrameworkCore
- Contains
IdentityDbContext
,UserStore
etc - Handles identity related data access (-> Database)
- Contains
Default identity entities
IdentityUser
- The default implementation of
IdentityUser<TKey>
which uses a string as a primary key - This implementation automatically sets this identifier as a string, which in turn it will automatically initialize as a GUID
- Designed to use every feature of ASP.NET Core Identity
- See:
public class IdentityUser : IdentityUser<string> {
// ... ... ...
string UserName { get; set; }
string NormalizedUserName { get; set; }
string Email { get; set; }
string NormalizedEmail { get; set; }
bool EmailConfirmed { get; set; }
string PasswordHash { get; set; }
string SecurityStamp { get; set; }
string PhoneNumber { get; set; }
bool PhoneNumberConfirmed { get; set; }
bool TwoFactorEnabled { get; set; }
DateTime? LockoutEndDateUtc { get; set; }
bool LockoutEnabled { get; set; }
int AccessFailedCount { get; set; }
}
IdentityUserClaim
- Represents a claim that a user possesses
- Allows us to store arbitrary claims for a user where a claim consists of a type and a value
- We would typically use this entity over a property on the user table
- IdentityUserClaim has a UserId property, linking us back to the owning user, meaning a user could have many claims
- See
public class IdentityUserClaim<TKey> {
public int Id { get; set; }
public string ClaimType { get; set; }
public string ClaimValue { get; set; }
public TKey UserId { get; set; }
public Claim ToClaim() { //... }
}
IdentityUserLogin
- IdentityUserLogin models an external identity (OpenID provider: Facebook, Google etc.) that links back to a local user entity
- LoginProvider is a unique value representing an external identity provider such as Google or Active Directory
- ProviderKey is the unique identifier for the user within that system
- See:
public class IdentityUserLogin<TKey> {
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
public string ProviderDisplayName { get; set; }
public TKey UserId { get; set; }
}
IdentityUserToken
- IdentityUserToken allows us to keep track of tokens returned by external identity providers, such as an identity token from an OpenID provider
- This entity is relatively new to ASP. NET Identity library
- See:
public class IdentityUserToken<TKey> {
public string Name { get; set; }
public string Value { get; set; }
public string LoginProvider { get; set; }
public TKey UserId { get; set; }
}
IdentityRole
- The default implementation of
IdentityRole<TKey>
which uses a string as the primary key. - IdentityRole is entity for modeling roles
- It has a couple of supporting entities:
IdentityRoleClaim
- assign claims to a role
- this means that any user who has this role will also have all of its role claims assigned to it
IdentityUserRole
- IdentityUserRole simply links a user to a role. This is necessary since a user can have many roles, and a role can have many users.
- Note that when we use this entity, both our role and our user objects must use the same type as our key
- See:
public class IdentityRole : IdentityRole<string> { //... }
public class IdentityRole<TKey> {
public TKey Id { get; set; }
public string Name { get; set; }
public string NormalizedName { get; set; }
}
public class IdentityRoleClaim<TKey> {
public int Id { get; set; }
public string ClaimType { get; set; }
public string ClaimValue { get; set; }
public TKey RoleId { get; set; }
public Claim ToClaim() { //... }
}
public class IdentityUserRole<TKey> {
public TKey UserId { get; set; }
public TKey RoleId { get; set; }
}
Exploring default implementation
- The defaulimplementation provides authentication and user management
- You can customize iby extending defaulimplementation
- To override UI, you need to sacffold Identity
- If any Identity is related UI is scaffold, aspnecore will use thaUI from app and the resfrom library (scaffolding => overriding the library)
Scaffolding default implementation
Step-1
Step-2
Step-3
Step-4
Step-5
Step-6
Step-7
Step-8
Step-9
Step-10
See: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity
Migration for identity store
Step-1
Step-2
Step-3
Step-4
Step-5
Step-6
Step-7
Step-8
See: https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/