asp.net core mvc 3.1 源码分析(四)
标签:iter client result smo tap map code argument ons
AuthorizationApplicationModelProvider
该类主要添加授权认证的过滤器
先在Controller和Action中找到实现IAuthorizeData的特性,再根据IAuthorizeData创建AuthorizeFilter过滤器,把AuthorizeFilter添加到Controller和Action的Filters列表中
具体的授权逻辑后面分开讲
internal class AuthorizationApplicationModelProvider : IApplicationModelProvider
{
private readonly MvcOptions _mvcOptions;
private readonly IAuthorizationPolicyProvider _policyProvider;
public AuthorizationApplicationModelProvider(
IAuthorizationPolicyProvider policyProvider,
IOptions mvcOptions)
{
_policyProvider = policyProvider;
_mvcOptions = mvcOptions.Value;
}
public int Order => -1000 + 10;
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
// Intentionally empty.
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (_mvcOptions.EnableEndpointRouting)
{
// When using endpoint routing, the AuthorizationMiddleware does the work that Auth filters would otherwise perform.
// Consequently we do not need to convert authorization attributes to filters.
return;
}
foreach (var controllerModel in context.Result.Controllers)
{
var controllerModelAuthData = controllerModel.Attributes.OfType().ToArray();
if (controllerModelAuthData.Length > 0)
{
controllerModel.Filters.Add(GetFilter(_policyProvider, controllerModelAuthData));
}
foreach (var attribute in controllerModel.Attributes.OfType())
{
controllerModel.Filters.Add(new AllowAnonymousFilter());
}
foreach (var actionModel in controllerModel.Actions)
{
var actionModelAuthData = actionModel.Attributes.OfType().ToArray();
if (actionModelAuthData.Length > 0)
{
actionModel.Filters.Add(GetFilter(_policyProvider, actionModelAuthData));
}
foreach (var attribute in actionModel.Attributes.OfType())
{
actionModel.Filters.Add(new AllowAnonymousFilter());
}
}
}
}
public static AuthorizeFilter GetFilter(IAuthorizationPolicyProvider policyProvider, IEnumerable authData)
{
// The default policy provider will make the same policy for given input, so make it only once.
// This will always execute synchronously.
if (policyProvider.GetType() == typeof(DefaultAuthorizationPolicyProvider))
{
var policy = AuthorizationPolicy.CombineAsync(policyProvider, authData).GetAwaiter().GetResult();
return new AuthorizeFilter(policy);
}
else
{
return new AuthorizeFilter(policyProvider, authData);
}
}
}
ApiBehaviorApplicationModelProvider
internal class ApiBehaviorApplicationModelProvider : IApplicationModelProvider
{
public ApiBehaviorApplicationModelProvider(
IOptions apiBehaviorOptions,
IModelMetadataProvider modelMetadataProvider,
IClientErrorFactory clientErrorFactory,
ILoggerFactory loggerFactory)
{
var options = apiBehaviorOptions.Value;
ActionModelConventions = new List()
{
new ApiVisibilityConvention(),
};
if (!options.SuppressMapClientErrors)
{
ActionModelConventions.Add(new ClientErrorResultFilterConvention());
}
if (!options.SuppressModelStateInvalidFilter)
{
ActionModelConventions.Add(new InvalidModelStateFilterConvention());
}
if (!options.SuppressConsumesConstraintForFormFileParameters)
{
ActionModelConventions.Add(new ConsumesConstraintForFormFileParameterConvention());
}
var defaultErrorType = options.SuppressMapClientErrors ? typeof(void) : typeof(ProblemDetails);
var defaultErrorTypeAttribute = new ProducesErrorResponseTypeAttribute(defaultErrorType);
ActionModelConventions.Add(new ApiConventionApplicationModelConvention(defaultErrorTypeAttribute));
if (!options.SuppressInferBindingSourcesForParameters)
{
ActionModelConventions.Add(new InferParameterBindingInfoConvention(modelMetadataProvider));
}
}
///
/// Order is set to execute after the and allow any other user
/// that configure routing to execute.
///
public int Order => -1000 + 100;
public List ActionModelConventions { get; }
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
foreach (var controller in context.Result.Controllers)
{
if (!IsApiController(controller))
{
continue;
}
foreach (var action in controller.Actions)
{
// Ensure ApiController is set up correctly
EnsureActionIsAttributeRouted(action);
foreach (var convention in ActionModelConventions)
{
convention.Apply(action);
}
}
}
}
private static void EnsureActionIsAttributeRouted(ActionModel actionModel)
{
if (!IsAttributeRouted(actionModel.Controller.Selectors) &&
!IsAttributeRouted(actionModel.Selectors))
{
// Require attribute routing with controllers annotated with ApiControllerAttribute
var message = Resources.FormatApiController_AttributeRouteRequired(
actionModel.DisplayName,
nameof(ApiControllerAttribute));
throw new InvalidOperationException(message);
}
bool IsAttributeRouted(IList selectorModel)
{
for (var i = 0; i )
{
if (selectorModel[i].AttributeRouteModel != null)
{
return true;
}
}
return false;
}
}
private static bool IsApiController(ControllerModel controller)
{
if (controller.Attributes.OfType().Any())
{
return true;
}
var controllerAssembly = controller.ControllerType.Assembly;
var assemblyAttributes = controllerAssembly.GetCustomAttributes();
return assemblyAttributes.OfType().Any();
}
}
该类涉及到webapi方面
对ActionModel设置相关的属性和过滤器
asp.net core mvc 3.1 源码分析(四)
标签:iter client result smo tap map code argument ons
原文地址:https://www.cnblogs.com/lanpingwang/p/12642751.html
评论