• aspnetcore 认证相关类简要说明三


    今天我们再来了解一个很重要的接口IAuthenticationService的实现类AuthenticationService:

    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接口实例,并调用同名方法。

    关于IAuthenticationService、IAuthenticationHandlerProvider和IAuthenticationSchemeProvider我们又是什么时候注入到服务容器里去的呢?它是在AuthenticationCoreServiceCollectionExtensions这个静态类中的AddAuthenticationCore扩展方法注入到容器中的,还有AuthenticationOptions也是在这里注入到依赖注入系统的容器中的:

        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方法调用的。这个就不贴代码了。

    注入完以后呢?怎么使用呢?为了方便使用,aspnetcore为我们在外面又裹了一层,那就是AuthenticationHttpContextExtensions为HttpContext添加的扩展方法。我们可以在Controller如下调用:

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

    至此认证相关的核心元素介绍完成,本篇到此结束。

  • 相关阅读:
    C#获取配置文件中的文件数据
    wpf MVVMLight的DataGrid绑定数据
    扫码支付自动跳转,可以使用第三方网站实现扫码二维码付款然后跳转到想要的页面展示想要内容或者是解压码或者是某个资源的下载页呢 具体步骤(我以你上传一个压缩包到某种网盘或者可以下载的地址等让人付费解压为例):
    oracle数据库如何创建用户以及分配权限
    ORA-12547: TNS: 丢失连接
    springmvc中applicationapplicationContext头部代码
    No mapping found for HTTP request with URI
    在Navicat新建用户
    myeclipse 项目引入 com.sun.image.codec.jpeg 的api报错解决方法
    java.lang.NullPointerException at org.apache.jsp.**_jsp.jspInit(**_jsp.java)tomcat启动异常解决方法
  • 原文地址:https://www.cnblogs.com/koeltp/p/9886651.html
Copyright © 2020-2023  润新知