正文

asp.net core 认证和授权实例详解(asp.net windows身份验证)干货满满

文章摘要

这篇文章介绍了Microsoft.AspNetCore Authorization middleware的实现,展示了如何自定义一个用于控制资源访问权限的middleware。核心内容包括: 1. **类的结构**:该middleware继承了Microsoft.AspNetCore's Authorization middleware,并引入了自定义的`IPolicyProvider`和`IAuthorizeData`接口。 2. **核心功能**: - **获取并合并作者信息**:通过`IPolicyProvider`和`IAuthorizeData`获取和合并用户所需的所有角色权限。 - **认证和授权检查**:使用`IPolicyEvaluator.AuthenticateAsync()`和`AuthorizeAsync()`方法对访问者进行认证,并根据资源需求进行授权。 - **挑战和禁止访问**:在授权失败时,通过`context.ChallengeAsync()`或`context.ForbidAsync()`方法处理未登录或无权限访问的情况。 3. **关键逻辑**: - 如果用户身份认证通过但无权限访问,则返回401未认证状态。 - 如果用户被禁止访问资源,则返回403禁止访问状态。 - 中ware通过整合作者信息和认证逻辑,实现了对资源访问权限的精细控制。 这篇文章展示了如何通过自定义middleware实现对资源访问权限的精细控制,适合需要复杂认证和授权场景的应用。

// Microsoft.AspNetCore.Authorization.AuthorizationMiddleware using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization.Policy; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; public class AuthorizationMiddleware { private const string AuthorizationMiddlewareInvokedWithEndpointKey=”__AuthorizationMiddlewareWithEndpointInvoked”; private static readonly object AuthorizationMiddlewareWithEndpointInvokedValue=new object(); private readonly RequestDelegate _next; private readonly IAuthorizationPolicyProvider _policyProvider; public AuthorizationMiddleware(RequestDelegate next, IAuthorizationPolicyProvider policyProvider) { _next=next throw new ArgumentNullException(“next”); _policyProvider=policyProvider throw new ArgumentNullException(“policyProvider”); } public async Task Invoke(HttpContext context) { if (context==null) { throw new ArgumentNullException(“context”); } Endpoint endpoint=context.GetEndpoint(); if (endpoint !=null) { context.Items[“__AuthorizationMiddlewareWithEndpointInvoked”]=AuthorizationMiddlewareWithEndpointInvokedValue; } //获取访问当前资源所需要的所有角色权限,及授权策略,以及访问该资源时需要使用的认证方案列表,并统一合并到一个AuthorizationPolicy对象中。 IReadOnlyList<IAuthorizeData> authorizeData=endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>() Array.Empty<IAuthorizeData>(); AuthorizationPolicy policy=await AuthorizationPolicy.CombineAsync(_policyProvider, authorizeData); if (policy==null) { await _next(context); return; } IPolicyEvaluator policyEvaluator=context.RequestServices.GetRequiredService<IPolicyEvaluator>(); //通过IPolicyEvaluator.AuthenticateAsync()方法,对当前访问者进行认证,至于使用哪种方案认证,根据该资源要求使用的认证方案来,如果没有指定, //则使用默认认证方案进行认证。 AuthenticateResult authenticationResult=await policyEvaluator.AuthenticateAsync(policy, context); //如果包含实现了IAllowAnonymous接口的特性,则不进行授权检查。 if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() !=null) { await _next(context); return; } //这里调用AuthorizeAsync进行授权检查,注意,这里将上一步认证结果authenticationResult也传到了授权检查方法内部。 PolicyAuthorizationResult policyAuthorizationResult=await policyEvaluator.AuthorizeAsync(policy, authenticationResult, context, endpoint); //检查授权结果,如果是未登录,则返回401未认证,让用户进行登录,如果该资源指定了特定的认证方案,则调用特定认证方案的Challenge方法, //否则调用默认认证方案的Challenge方法,通常Challenge做的事情就是重定向用户的浏览器到登录页面或者对于ajax异步请求返回401. if (policyAuthorizationResult.Challenged) { if (policy.AuthenticationSchemes.Any()) { foreach (string authenticationScheme in policy.AuthenticationSchemes) { await context.ChallengeAsync(authenticationScheme); } } else { await context.ChallengeAsync(); } } //如果当前访问者用户身份认证通过,但是不被允许访问该资源的权限,那么默认返回401(禁止访问)给浏览器端,通常对于未授权的访问请求,应用常常的做法是将用户的浏览器重定向到禁止访问的提示页面,或者对于ajax异步请求来说,通常返回403状态码,和上面未认证情况一样,如果该资源指定了特定的认证方案,那么会调用特定认证方案的Forbid方法,否则调用默认认证方案的Forbid方法。 else if (policyAuthorizationResult.Forbidden) { if (policy.AuthenticationSchemes.Any()) { foreach (string authenticationScheme2 in policy.AuthenticationSchemes) { await context.ForbidAsync(authenticationScheme2); } } else { await context.ForbidAsync(); } } else { await _next(context); } } }