aspnetcore 認證相關類簡要說明三

今天咱們再來了解一個很重要的接口IAuthenticationService的實現類AuthenticationService:async

public class AuthenticationService : IAuthenticationService
{
        public AuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform)
        {
            Schemes = schemes;
            Handlers = handlers;
            Transform = transform;
        }

        public IAuthenticationSchemeProvider Schemes { get; }
        public IAuthenticationHandlerProvider Handlers { get; }
        public IClaimsTransformation Transform { get; }

        public virtual async Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme)
        {
            if (scheme == null)
            {
                var defaultScheme = await Schemes.GetDefaultAuthenticateSchemeAsync();
                scheme = defaultScheme?.Name;
                if (scheme == null)
                {
                    throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultAuthenticateScheme found.");
                }
            }

            var handler = await Handlers.GetHandlerAsync(context, scheme);
            if (handler == null)
            {
                throw await CreateMissingHandlerException(scheme);
            }

            var result = await handler.AuthenticateAsync();
            if (result != null && result.Succeeded)
            {
                var transformed = await Transform.TransformAsync(result.Principal);
                return AuthenticateResult.Success(new AuthenticationTicket(transformed, result.Properties, result.Ticket.AuthenticationScheme));
            }
            return result;
        }

        /// <summary>
        /// Challenge the specified authentication scheme.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/>.</param>
        /// <param name="scheme">The name of the authentication scheme.</param>
        /// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
        /// <returns>A task.</returns>
        public virtual async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
        {
            if (scheme == null)
            {
                var defaultChallengeScheme = await Schemes.GetDefaultChallengeSchemeAsync();
                scheme = defaultChallengeScheme?.Name;
                if (scheme == null)
                {
                    throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultChallengeScheme found.");
                }
            }

            var handler = await Handlers.GetHandlerAsync(context, scheme);
            if (handler == null)
            {
                throw await CreateMissingHandlerException(scheme);
            }

            await handler.ChallengeAsync(properties);
        }

        /// <summary>
        /// Forbid the specified authentication scheme.
        /// </summary>
        public virtual async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)
        {
            if (scheme == null)
            {
                var defaultForbidScheme = await Schemes.GetDefaultForbidSchemeAsync();
                scheme = defaultForbidScheme?.Name;
                ...
            }

            var handler = await Handlers.GetHandlerAsync(context, scheme);
       ...
await handler.ForbidAsync(properties); } /// <summary> /// Sign a principal in for the specified authentication scheme. /// </summary> public virtual async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) {
       ...
       
if (scheme == null) { var defaultScheme = await Schemes.GetDefaultSignInSchemeAsync(); scheme = defaultScheme?.Name; ... } var handler = await Handlers.GetHandlerAsync(context, scheme); ...
       
var signInHandler = handler as IAuthenticationSignInHandler; ...
       
await signInHandler.SignInAsync(principal, properties); } /// <summary> /// Sign out the specified authentication scheme. /// </summary> public virtual async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties) { if (scheme == null) { var defaultScheme = await Schemes.GetDefaultSignOutSchemeAsync(); scheme = defaultScheme?.Name; if (scheme == null) { throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultSignOutScheme found."); } } var handler = await Handlers.GetHandlerAsync(context, scheme); if (handler == null) { throw await CreateMissingSignOutHandlerException(scheme); } var signOutHandler = handler as IAuthenticationSignOutHandler; if (signOutHandler == null) { throw await CreateMismatchedSignOutHandlerException(scheme, handler); } await signOutHandler.SignOutAsync(properties); }
}

該類經過構造方法,將咱們前兩篇中講到了IAuthenticationSchemeProviderIAuthenticationHandlerProvider注入了進來,第三個參數不是很重要就飄過了。接下來咱們看看它的這幾個方法AuthenticateAsync、ChallengeAsync、ForbidAsync、SignInAsync和SignOutAsync等方法,他們的套路幾乎都同樣的,經過注入進來的兩個接口的實例,最終得到到IAuthenticationHandler接口實例,並調用同名方法。ide

關於IAuthenticationService、IAuthenticationHandlerProvider和IAuthenticationSchemeProvider咱們又是何時注入到服務容器裏去的呢?它是在AuthenticationCoreServiceCollectionExtensions這個靜態類中的AddAuthenticationCore擴展方法注入到容器中的,還有AuthenticationOptions也是在這裏注入到依賴注入系統的容器中的:oop

    public static class AuthenticationCoreServiceCollectionExtensions
    {
        public static IServiceCollection AddAuthenticationCore(this IServiceCollection services)
        {
       ...
services.TryAddScoped<IAuthenticationService, AuthenticationService>(); services.TryAddSingleton<IClaimsTransformation, NoopClaimsTransformation>(); // Can be replaced with scoped ones that use DbContext services.TryAddScoped<IAuthenticationHandlerProvider, AuthenticationHandlerProvider>(); services.TryAddSingleton<IAuthenticationSchemeProvider, AuthenticationSchemeProvider>(); return services; } public static IServiceCollection AddAuthenticationCore(this IServiceCollection services, Action<AuthenticationOptions> configureOptions) { ... services.AddAuthenticationCore(); services.Configure(configureOptions); return services; } }

該擴展方法是在Startup的ConfigureServices方法調用的。這個就不貼代碼了。this

注入完之後呢?怎麼使用呢?爲了方便使用,aspnetcore爲咱們在外面又裹了一層,那就是AuthenticationHttpContextExtensions爲HttpContext添加的擴展方法。咱們能夠在Controller以下調用:spa

public class HomeController : Controller
{
        public IActionResult Index()
        {
            var result = HttpContext.AuthenticateAsync();
            return View(result.Result);
        }
}

至此認證相關的核心元素介紹完成,本篇到此結束。code

相關文章
相關標籤/搜索