// 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);
}
}
}
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);
}
}
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。