有哪些单页网站百度推广网页制作
有哪些单页网站,百度推广网页制作,广告推广怎么做最有效,网站html源码下载在上一章中ASP.NET Core 认证与授权[5]:初识授权#xff0c;详细介绍了 ASP.NET Core 中的授权策略#xff0c;在需要授权时#xff0c;只需要在对应的Controler或者Action上面打上[Authorize]特性#xff0c;并指定要执行的策略名称即可#xff0c;但是#xff0c;授权策… 在上一章中ASP.NET Core 认证与授权[5]:初识授权详细介绍了 ASP.NET Core 中的授权策略在需要授权时只需要在对应的Controler或者Action上面打上[Authorize]特性并指定要执行的策略名称即可但是授权策略是怎么执行的呢怀着一颗好奇的心忍不住来探索一下它的执行流程。 在《(上一章》中提到AuthorizeAttribute只是一个简单的实现了IAuthorizeData接口的特性并且在 ASP.NET Core 授权系统中并没有使用到它。我们知道在认证中还有一个UseAuthentication扩展方法来激活认证系统但是在授权中并没有类似的机制。 这是因为当我们使用[Authorize]通常是在MVC中由MVC来负责激活授权系统。本来在这个系列的文章中我并不想涉及到MVC的知识但是为了能更好的理解授权系统的执行就来简单介绍一下MVC中与授权相关的知识。 MVC中的授权 当我们使用MVC时首先会调用MVC的AddMvc扩展方法用来注册一些MVC相关的服务 public static IMvcBuilder AddMvc(this IServiceCollection services){ var builder services.AddMvcCore();builder.AddAuthorization();...
}public static IMvcCoreBuilder AddAuthorization(this IMvcCoreBuilder builder){AddAuthorizationServices(builder.Services); return builder;
}internal static void AddAuthorizationServices(IServiceCollection services){services.AddAuthenticationCore();services.AddAuthorization();services.AddAuthorizationPolicyEvaluator();services.TryAddEnumerable(ServiceDescriptor.TransientIApplicationModelProvider, AuthorizationApplicationModelProvider());
} 在上面AddAuthorizationServices中的前三个方法都属于 ASP.NET Core 《Security》项目中提供的扩展方法其中前两个在前面几章已经介绍过了对于AddAuthorizationPolicyEvaluator放到后面再来介绍我们先来看一下MVC中的AuthorizationApplicationModelProvider。 AuthorizationApplicationModelProvider 在MVC中有一个ApplicationModel的概念它用来封装Controller, Filter, ApiExplorer等。对应的在MVC中还提供了一系列的ApplicationModelProvider来初始化ApplicationModel的各个部分而AuthorizationApplicationModelProvider就是用来初始化与授权相关的部分。 public class AuthorizationApplicationModelProvider : IApplicationModelProvider{ public void OnProvidersExecuting(ApplicationModelProviderContext context) { foreach (var controllerModel in context.Result.Controllers){ var controllerModelAuthData controllerModel.Attributes.OfTypeIAuthorizeData().ToArray(); if (controllerModelAuthData.Length 0){controllerModel.Filters.Add(GetFilter(_policyProvider, controllerModelAuthData));} foreach (var attribute in controllerModel.Attributes.OfTypeIAllowAnonymous()){controllerModel.Filters.Add(new AllowAnonymousFilter());} foreach (var actionModel in controllerModel.Actions){ var actionModelAuthData actionModel.Attributes.OfTypeIAuthorizeData().ToArray(); if (actionModelAuthData.Length 0){actionModel.Filters.Add(GetFilter(_policyProvider, actionModelAuthData));} foreach (var attribute in actionModel.Attributes.OfTypeIAllowAnonymous()){actionModel.Filters.Add(new AllowAnonymousFilter());}}}}
} 如上首先查找每个Controller中实现了IAuthorizeData接口的特性然后将其转化为AuthorizeFilter并添加到Controller的Filter集合中紧接着再查找实现了IAllowAnonymous接口的特性将其转化为AllowAnonymousFilter过滤器也添加到Filter集合中然后以同样的逻辑查找Action上的特性并添加到Action的Filter集合中。 其中的关键点就是将IAuthorizeData也就是通过我们熟悉的[Authorize]特性转化为MVC中的AuthorizeFilter过滤器 public static AuthorizeFilter GetFilter(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authData){ if (policyProvider.GetType() typeof(DefaultAuthorizationPolicyProvider)){ var policy AuthorizationPolicy.CombineAsync(policyProvider, authData).GetAwaiter().GetResult(); return new AuthorizeFilter(policy);} else{ return new AuthorizeFilter(policyProvider, authData);}
} CombineAsync在上一章的《AuthorizationPolicy》中已经介绍过了我们往下看看AuthorizeFilter的实现。 AuthorizeFilter 在MVC中有一个AuthorizeFilter过滤器类似我们在ASP.NET 4.x中所熟悉的[Authorize]它实现了IAsyncAuthorizationFilter接口定义如下 public class AuthorizeFilter : IAsyncAuthorizationFilter, IFilterFactory{ public AuthorizeFilter(AuthorizationPolicy policy) {} public AuthorizeFilter(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authorizeData) : this(authorizeData) {} public AuthorizeFilter(IEnumerableIAuthorizeData authorizeData) {} public IEnumerableIAuthorizeData AuthorizeData { get; } public AuthorizationPolicy Policy { get; } public virtual async Task OnAuthorizationAsync(AuthorizationFilterContext context) { var effectivePolicy Policy; if (effectivePolicy null){effectivePolicy await AuthorizationPolicy.CombineAsync(PolicyProvider, AuthorizeData);} var policyEvaluator context.HttpContext.RequestServices.GetRequiredServiceIPolicyEvaluator(); var authenticateResult await policyEvaluator.AuthenticateAsync(effectivePolicy, context.HttpContext); if (context.Filters.Any(item item is IAllowAnonymousFilter)){ return;} var authorizeResult await policyEvaluator.AuthorizeAsync(effectivePolicy, authenticateResult, context.HttpContext, context);... // 如果授权失败返回ChallengeResult或ForbidResult}
} AuthorizeFilter的OnAuthorizationAsync方法会在Action执行之前触发其调用IPolicyEvaluator来完成授权将执行流程切回到 ASP.NET Core 授权系统中。关于MVC中IApplicationModelProvider以及Filter的概念在以后MVC系列的文章中再来详细介绍下面就继续介绍 ASP.NET Core 的授权系统也就是《Security》项目。 IPolicyEvaluator IPolicyEvaluator是MVC调用授权系统的入口点其定义如下 public interface IPolicyEvaluator{ TaskAuthenticateResult AuthenticateAsync(AuthorizationPolicy policy, HttpContext context); TaskPolicyAuthorizationResult AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context, object resource);
} 在上面介绍的AddMVC中调用了AddAuthorizationPolicyEvaluator扩展方法它有如下定义 public static class PolicyServiceCollectionExtensions{ public static IServiceCollection AddAuthorizationPolicyEvaluator(this IServiceCollection services) {services.TryAdd(ServiceDescriptor.TransientIPolicyEvaluator, PolicyEvaluator()); return services;}
} 由此可知IPolicyEvaluator的默认实现为PolicyEvaluator我们就从它入手来一步一步解剖 ASP.NET Core 授权系统的执行步骤。 在AuthorizeFilter中依次调到了AuthenticateAsync和AuthorizeAsync方法我们就一一来看。 AuthenticateAsync(AuthenticationSchemes) 为什么还有一个AuthenticateAsync方法呢这不是在认证阶段执行的吗我们看下它的实现 public class PolicyEvaluator : IPolicyEvaluator{ public virtual async TaskAuthenticateResult AuthenticateAsync(AuthorizationPolicy policy, HttpContext context) { if (policy.AuthenticationSchemes ! null policy.AuthenticationSchemes.Count 0){ClaimsPrincipal newPrincipal null; foreach (var scheme in policy.AuthenticationSchemes){ var result await context.AuthenticateAsync(scheme); if (result ! null result.Succeeded){newPrincipal SecurityHelper.MergeUserPrincipal(newPrincipal, result.Principal);}} if (newPrincipal ! null){context.User newPrincipal; return AuthenticateResult.Success(new AuthenticationTicket(newPrincipal, string.Join(;, policy.AuthenticationSchemes)));} else{context.User new ClaimsPrincipal(new ClaimsIdentity()); return AuthenticateResult.NoResult();}} return (context.User?.Identity?.IsAuthenticated ?? false) ? AuthenticateResult.Success(new AuthenticationTicket(context.User, context.User)): AuthenticateResult.NoResult();}
} 在《上一章》中我们知道在AuthorizationPolicy中有AuthenticationSchemes和IAuthorizationRequirement两个属性并详细介绍介绍了Requirement但是没有提到AuthenticationSchemes的调用。 那么看到这里也就大概明白了它与Requirements的执行是完全独立的并在它之前执行用于重置Claims那么为什么要重置呢 在认证的章节介绍过在认证阶段只会执行默认的认证Schemecontext.User就是使用context.AuthenticateAsync(DefaultAuthenticateScheme)来赋值的当我们希望使用非默认的Scheme或者是想合并多个认证Scheme的Claims时就需要使用基于Scheme的授权来重置Claims了。 它的实现也很简单直接使用我们在授权策略中指定的Schemes来依次调用认证服务的AuthenticateAsync方法并将生成的Claims合并最后返回我们熟悉的AuthenticateResult认证结果。 AuthorizeAsync(Requirements) 接下来再看一下PolicyEvaluator的AuthorizeAsync方法 public class PolicyEvaluator : IPolicyEvaluator{ private readonly IAuthorizationService _authorization; public PolicyEvaluator(IAuthorizationService authorization) {_authorization authorization;} public virtual async TaskPolicyAuthorizationResult AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context, object resource) { var result await _authorization.AuthorizeAsync(context.User, resource, policy); if (result.Succeeded) return PolicyAuthorizationResult.Success(); return (authenticationResult.Succeeded) ? PolicyAuthorizationResult.Forbid() : PolicyAuthorizationResult.Challenge();}
} 该方法会根据Requirements来完成授权具体的实现是通过调用IAuthorizationService来实现的。 最终返回的是一个PolicyAuthorizationResult对象并在授权失败时根据认证结果来返回Forbid(未授权)或Challenge(未登录)。 public class PolicyAuthorizationResult{ private PolicyAuthorizationResult() { } public bool Challenged { get; private set; } public bool Forbidden { get; private set; } public bool Succeeded { get; private set; }
} IAuthorizationService 然后就到了授权的核心对象AuthorizationService也可以称为授权的外交官我们也可以直接在应用代码中调用该对象来实现授权它有如下定义 public interface IAuthorizationService{ TaskAuthorizationResult AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName); TaskAuthorizationResult AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerableIAuthorizationRequirement requirements);
} 在AuthorizeAsync中还涉及到一个resource对象用来实现面向资源的授权放在下一章中再来介绍而在本章与《前一章》的示例中该值均为null。 ASP.NET Core 中还为IAuthorizationService提供了几个扩展方法 public static class AuthorizationServiceExtensions{ public static TaskAuthorizationResult AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, string policyName) {} public static TaskAuthorizationResult AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, AuthorizationPolicy policy) {} public static TaskAuthorizationResult AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, object resource, IAuthorizationRequirement requirement) {} public static TaskAuthorizationResult AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, object resource, AuthorizationPolicy policy) {}
} 其默认实现为DefaultAuthorizationService: public class DefaultAuthorizationService : IAuthorizationService{ private readonly AuthorizationOptions _options; private readonly IAuthorizationHandlerContextFactory _contextFactory; private readonly IAuthorizationHandlerProvider _handlers; private readonly IAuthorizationEvaluator _evaluator; private readonly IAuthorizationPolicyProvider _policyProvider; public async TaskAuthorizationResult AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName) { var policy await _policyProvider.GetPolicyAsync(policyName); return await this.AuthorizeAsync(user, resource, policy);} public async TaskAuthorizationResult AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerableIAuthorizationRequirement requirements) { var authContext _contextFactory.CreateContext(requirements, user, resource); var handlers await _handlers.GetHandlersAsync(authContext); foreach (var handler in handlers){ await handler.HandleAsync(authContext); if (!_options.InvokeHandlersAfterFailure authContext.HasFailed){ break;}} return _evaluator.Evaluate(authContext);}
} 通过上面代码可以看出在《上一章》中介绍的授权策略在这里获取到它的Requirements后续便不再需要了。而在AuthorizationService中是通过调用四大核心对象来完成授权我们一一来看。 IAuthorizationPolicyProvider 由于在[Authorize]中我们指定的是策略的名称因此需要使用IAuthorizationPolicyProvider来根据名称获取到策略对象默认实现为DefaultAuthorizationPolicyProvider public class DefaultAuthorizationPolicyProvider : IAuthorizationPolicyProvider{ private readonly AuthorizationOptions _options; public TaskAuthorizationPolicy GetDefaultPolicyAsync() { return Task.FromResult(_options.DefaultPolicy);} public virtual TaskAuthorizationPolicy GetPolicyAsync(string policyName) { return Task.FromResult(_options.GetPolicy(policyName));}
} 在上一章中介绍过我们定义的策略都保存在《AuthorizationOptions》的字典中因此在这里只是简单的将AuthorizationOptions中的同名方法异步化。 IAuthorizationHandlerContextFactory 授权上下文是我们接触较多的对象当我们自定义授权Handler时就会用到它它是使用简单工厂模式来创建的 public class DefaultAuthorizationHandlerContextFactory : IAuthorizationHandlerContextFactory{ public virtual AuthorizationHandlerContext CreateContext(IEnumerableIAuthorizationRequirement requirements, ClaimsPrincipal user, object resource) { return new AuthorizationHandlerContext(requirements, user, resource);}
} 授权上下文中主要包含用户的Claims和授权策略的Requirements public class AuthorizationHandlerContext{ private HashSetIAuthorizationRequirement _pendingRequirements; private bool _failCalled; private bool _succeedCalled; public AuthorizationHandlerContext(IEnumerableIAuthorizationRequirement requirements, ClaimsPrincipal user, object resource) {Requirements requirements; User user; Resource resource;_pendingRequirements new HashSetIAuthorizationRequirement(requirements);} public virtual bool HasFailed { get { return _failCalled; } } public virtual bool HasSucceeded !_failCalled _succeedCalled !_pendingRequirements.Any(); public virtual void Fail() {_failCalled true;} public virtual void Succeed(IAuthorizationRequirement requirement) {_succeedCalled true;_pendingRequirements.Remove(requirement);}
} 如上_pendingRequirements中保存着所有待验证的Requirements验证成功的Requirement则从中移除。 IAuthorizationHandlerProvider 兜兜转转终于进入到了授权的最终验证逻辑中了首先使用IAuthorizationHandlerProvider来获取到所有的授权Handler。 IAuthorizationHandlerProvider的默认实现为DefaultAuthorizationHandlerProvider: public class DefaultAuthorizationHandlerProvider : IAuthorizationHandlerProvider{ private readonly IEnumerableIAuthorizationHandler _handlers; public DefaultAuthorizationHandlerProvider(IEnumerableIAuthorizationHandler handlers) {_handlers handlers;} public TaskIEnumerableIAuthorizationHandler GetHandlersAsync(AuthorizationHandlerContext context) Task.FromResult(_handlers);
} 在《上一章》中我们还介绍到我们定义的Requirement可以直接实现IAuthorizationHandler接口也可以单独定义Handler但是需要注册到DI系统中去。 在默认的AuthorizationHandlerProvider中会从DI系统中获取到我们注册的所有Handler最终调用其HandleAsync方法。 我们在实现IAuthorizationHandler接口时通常是继承自AuthorizationHandlerTRequirement来实现它有如下定义 public abstract class AuthorizationHandlerTRequirement : IAuthorizationHandler where TRequirement : IAuthorizationRequirement{ public virtual async Task HandleAsync(AuthorizationHandlerContext context) { foreach (var req in context.Requirements.OfTypeTRequirement()){ await HandleRequirementAsync(context, req);}} protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement);
} 如上首先会在HandleAsync过滤出与Requirement对匹配的Handler然后再调用其HandleRequirementAsync方法。 那我们定义的直接实现IAuthorizationHandler了接口的Requirement又是如何执行的呢 在AddAuthorization扩展方法中可以看到默认还为IAuthorizationHandler注册了一个PassThroughAuthorizationHandler定义如下 public class PassThroughAuthorizationHandler : IAuthorizationHandler{ public async Task HandleAsync(AuthorizationHandlerContext context) { foreach (var handler in context.Requirements.OfTypeIAuthorizationHandler()){ await handler.HandleAsync(context);}}
} 它负责调用该策略中所有实现了IAuthorizationHandler接口的Requirement。 IAuthorizationEvaluator 最后通过调用IAuthorizationEvaluator接口来完成最终的授权结果默认实现为DefaultAuthorizationEvaluator: public class DefaultAuthorizationEvaluator : IAuthorizationEvaluator{ public AuthorizationResult Evaluate(AuthorizationHandlerContext context) context.HasSucceeded? AuthorizationResult.Success(): AuthorizationResult.Failed(context.HasFailed? AuthorizationFailure.ExplicitFail(): AuthorizationFailure.Failed(context.PendingRequirements));
} 当我们在一个策略中指定多个Requirement时只有全部验证通过时授权上下文中的HasSucceeded才会为True而HasFailed代表授权结果的显式失败。 这里根据授权上下文的验证结果来生成授权结果 public class AuthorizationResult{ public bool Succeeded { get; private set; } public AuthorizationFailure Failure { get; private set; } public static AuthorizationResult Success() new AuthorizationResult { Succeeded true }; public static AuthorizationResult Failed(AuthorizationFailure failure) new AuthorizationResult { Failure failure }; public static AuthorizationResult Failed() new AuthorizationResult { Failure AuthorizationFailure.ExplicitFail() };
}public class AuthorizationFailure{ private AuthorizationFailure() { } public bool FailCalled { get; private set; } public IEnumerableIAuthorizationRequirement FailedRequirements { get; private set; } public static AuthorizationFailure ExplicitFail() { return new AuthorizationFailure { FailCalled true, FailedRequirements new IAuthorizationRequirement[0] }; } public static AuthorizationFailure Failed(IEnumerableIAuthorizationRequirement failed) new AuthorizationFailure { FailedRequirements failed }; } 整个授权流程的结构大致如下 总结 通过对 ASP.NET Core 授权系统执行流程的探索可以看出授权是主要是通过调用IAuthorizationService来完成的而授权策略的本质是提供 Requirement 我们完全可以使用它们两个来完成各种灵活的授权方式而不用局限于策略。在 ASP.NET Core 中还提供了基于资源的授权放在下一章中来介绍并会简单演示一下在一个通用权限管理系统中如何来授权。 相关文章 ASP.NET Core 认证与授权[4]:JwtBearer认证 ASP.NET Core 认证与授权[2]:Cookie认证 ASP.NET Core 认证与授权[3]:OAuth OpenID Connect认证 Asp.Net Core 2.0 多角色权限认证 asp.net core 2.0 web api基于JWT自定义策略授权 ASP.NET Core 认证与授权[5]:初识授权 原文http://www.cnblogs.com/RainingNight/p/authorize-how-to-work-in-asp-net-core.html .NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/90237.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!