ASP.NET Core Authentication认证实现要领
public class AuthenticationSchemeProvider : IAuthenticationSchemeProvider { private readonly object _lock = new object(); private readonly AuthenticationOptions _options; private readonly IDictionary<string, AuthenticationScheme> _schemes; private readonly List<AuthenticationScheme> _requestHandlers; /// <summary> /// Creates an instance of <see cref="T:Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider" /> /// using the specified <paramref />, /// </summary> public AuthenticationSchemeProvider(IOptions<AuthenticationOptions> options) : this(options, (IDictionary<string, AuthenticationScheme>) new Dictionary<string, AuthenticationScheme>((IEqualityComparer<string>) StringComparer.Ordinal)) { } /// <summary> /// Creates an instance of <see cref="T:Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider" /> /// using the specified <paramref /> and <paramref />. /// </summary> protected AuthenticationSchemeProvider( IOptions<AuthenticationOptions> options, IDictionary<string, AuthenticationScheme> schemes) { this._options = options.Value; IDictionary<string, AuthenticationScheme> dictionary = schemes; if (dictionary == null) throw new ArgumentNullException(nameof (schemes)); this._schemes = dictionary; this._requestHandlers = new List<AuthenticationScheme>(); foreach (AuthenticationSchemeBuilder scheme in this._options.Schemes) this.AddScheme(scheme.Build()); } public virtual void AddScheme(AuthenticationScheme scheme) { if (this._schemes.ContainsKey(scheme.Name)) throw new InvalidOperationException("Scheme already exists: " + scheme.Name); lock (this._lock) { if (this._schemes.ContainsKey(scheme.Name)) throw new InvalidOperationException("Scheme already exists: " + scheme.Name); if (typeof (IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType)) this._requestHandlers.Add(scheme); this._schemes[scheme.Name] = scheme; } } ..... } 这对象就是把我们在认证注册处事中指定的scheme,通过理会出的AuthenticationSchemeProvider 的结构函数加载来的,进而返回一系列的List<AuthenticationScheme>,OK拿到这些scheme之后有什么用呢?这里引出了我们的第二个工具AuthenticationHandlerProvider,下面我们来相识一下。 IAuthenticationHandlerProvider 我们看到,AuthenticationMiddleware顶用到了IAuthenticationHandlerProvider的GetHandlerAsync要领,那我们先看一下这个要领的浸染 public class AuthenticationHandlerProvider : IAuthenticationHandlerProvider { private Dictionary<string, IAuthenticationHandler> _handlerMap = new Dictionary<string, IAuthenticationHandler>((IEqualityComparer<string>) StringComparer.Ordinal); /// <summary>Constructor.</summary> public AuthenticationHandlerProvider(IAuthenticationSchemeProvider schemes) { this.Schemes = schemes; } /// <summary> /// The <see cref="T:Microsoft.AspNetCore.Authentication.IAuthenticationHandlerProvider" />. /// </summary> public IAuthenticationSchemeProvider Schemes { get; } /// <summary>Returns the handler instance that will be used.</summary> public async Task<IAuthenticationHandler> GetHandlerAsync( HttpContext context, string authenticationScheme) { if (this._handlerMap.ContainsKey(authenticationScheme)) return this._handlerMap[authenticationScheme]; AuthenticationScheme schemeAsync = await this.Schemes.GetSchemeAsync(authenticationScheme); if (schemeAsync == null) return (IAuthenticationHandler) null; IAuthenticationHandler handler = (context.RequestServices.GetService(schemeAsync.HandlerType) ?? ActivatorUtilities.CreateInstance(context.RequestServices, schemeAsync.HandlerType)) as IAuthenticationHandler; if (handler != null) { await handler.InitializeAsync(schemeAsync, context); this._handlerMap[authenticationScheme] = handler; } return handler; } } 在建设Handler的时辰,是先从AuthenticationScheme中获取,假如不存在则通过ActivatorUtilities建设。 获取到Handle后,将会放在_handlerMap字典内里,当下次获取Handler的时辰,将直接从缓存中获取。 IAuthenticationService 这个工具是在AuthenticationMiddleware中最后才用到的,并且是基于HttpContext的扩展被挪用 public static class AuthenticationHttpContextExtensions { public static Task<AuthenticateResult> AuthenticateAsync(this HttpContext context, string scheme) => context.RequestServices.GetRequiredService<IAuthenticationService>().AuthenticateAsync(context, scheme); .... } 这里首要挪用了IAuthenticationService的AuthenticateAsync要领,看一下这个要领做了什么 public class AuthenticationService : IAuthenticationService { 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 scheme = (await this.Schemes.GetDefaultAuthenticateSchemeAsync())?.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 this.CreateMissingHandlerException(scheme); AuthenticateResult result = await handler.AuthenticateAsync(); if (result != null && result.Succeeded) return AuthenticateResult.Success(new AuthenticationTicket(await Transform.TransformAsync(result.Principal), result.Properties, result.Ticket.AuthenticationScheme)); return result; } } (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |