In depth interpretation of ASP. NET Core identity authentication process implementation

  • 2021-11-24 01:14:00
  • OfStack

To make a long story short: What the hell is ASP. NET Core declarative access control?
Today we go after the victory: Talk 1 about authentication in ASP. NET Core.

Authentication is the process of determining the identity of a user. Authorization is the process of determining whether a user has access to a resource.

1. All things change

Obviously, a general authentication use case consists of two parts:
Authenticate the user
React when an unauthenticated user attempts to access a restricted resource

Registered authentication handlers and their configuration options are referred to as "scenarios," which can be used as a mechanism for users to refer to the authentication, challenge, and disable behaviors of related handlers.

What we often say verbally:
Based on the cookie authentication scheme, if the authentication is successful, go on, if the authentication fails, jump back to the login page;
Based on the basic identity authentication (BA) scheme, if the authentication is successful, go on, if the authentication fails, the WWW-Authenticate header will be returned to the browser, and the browser will pop up the authentication window again.

2. ASP. NET Core certification principle

In ASP. NET Core, IAuthenticationService is responsible for authentication. The authentication service calls the registered authentication handler to complete the operation related to authentication, and the whole authentication process is concatenated by authentication middleware.

There are several key steps

1. Authentication Handler
The authentication processing program can be written in combination with the configuration item AuthenticationSchemeOptions in the scheme Scheme.

The authentication scheme based on Cookie can specify the login address in Options entry,
The authentication scheme based on basic identity can specify user name/password in Options item;

2. The authentication program inherits from AuthenticationHandler class or IAuthenticationHandler interface.

The core authentication function can implement claim-based access control and generate AuthenticationTicket objects bound with ClaimsPrincipal and Scheme; The function returns an AuthenticateResult object regardless of whether authentication succeeds or fails.

Challenges (response to unauthenticated users): For example, returning to the login page

Prohibited (response to authenticated but unauthorized access to specific resources): for example, return prompt string

All of the above are service registration processes

Upon receiving the request, the authentication middleware uses IAuthenticationService to authenticate HttpContext according to the required scheme, and the authentication handler written in Step 2 will be called internally.

Before the above authentication principle, there was a close combat: ASP. NET Core realized basic authentication.
The source code is as follows: https://www. ofstack. com/article/196974. htm

3. ASP. NET Core Get Current User

Based on declarative access control, we store identity information in the HttpContext. User property.


 var claims = new[] {
        new Claim(ClaimTypes.NameIdentifier,username),
        new Claim(ClaimTypes.Name,username),
      };
 var identity = new ClaimsIdentity(claims, Scheme.Name);
 var principal = new ClaimsPrincipal(identity);
 Context.User = principal;

There are two code scenarios for getting the currently logged-in user in an Web application:

3.1 Get the current logged-in user in the controller

The controller is a first-class citizen who handles requests and is born with HttpContext.
Get the User object directly through the HttpContext property contained in the ControllerBase base class.

In fact, Razor Page, Razor View and Middleware all contain HttpContext attributes/parameters, which can be used directly.

3.2 Get the current logged-in user in the service

At this point, the service is a part of request processing and no HttpContext is directly available.
ASP. NET Core provides the IHttpContextAccessor class that can inject the HttpContext object in this request (the role of the dependency injection framework).


//  The following user entity class, you need to get the current login user, with the help of IHttpContextAccessor Injection httpContext
public class UserEntityService : IUserEntityService
{
  private IHttpContextAccessor _accessor;
  private readonly IMongoCollection<UserProfile> _users;

  public UserEntityService(IHttpContextAccessor accessor, IDefaultMongoDatabaseProvider databaseProvider)
  {
    _accessor = accessor;
    _users = databaseProvider.GetCollection<UserProfile>(CollectionNames.UserProfiles);
  }

  public Task<UserProfile> GetCurrentUserAsync()
  {
    var rawUser = this._accessor.HttpContext.User();
    if (rawUser == null)
    {
     return null;
    }
    var filter = Builders<UserProfile>.Filter.Eq("UserId", rawUser.UserId);
   return _users.Find(filter).FirstOrDefaultAsync();
  }
}

We don't need to distinguish the above code occasions, and use ICurrentUser interface to get the logged-in user in Controller or Application service.

Narration

Personally, the source code of ASP. NET Core identity authentication is refined based on realistic cognition, which makes us marvel at the conciseness and refinement of the framework code.

Claims-based access control has become a standard and is fully supported by ASP. NET Core/abp vnext.


Related articles: