fuente AspNetCore3.1_Secutiry análisis sintáctico marco de autorización _8_Authorization_

directorio

breve introducción

La apertura se ha mencionado, la principal solución está certificada ¿quién es usted, autorizado para resolver el problema es que son permitidos. Varios marco de autenticación puede ayudarnos a conocer la identidad del usuario (reclamaciones), campo de alcance oauth como la arquitectura capaz de controlar el nivel de acceso a los servicios de la API, pero más refinado y funciones variadas que su alcance autorizado de tratamiento.

Autorización del programa de Microsoft proporciona marco flexible de autorización basada en políticas.

Vea a continuación para conocer el blog recomendada, estudio y sobre todo de detectar la fuente.

https://www.cnblogs.com/RainingNight/p/authorization-in-asp-net-core.html

inyección de dependencia

La inyección de las siguientes interfaces proporcionan una implementación por defecto

  • IAuthorizationService: Autorizado, Servicio de maletero
  • IAuthorizationPolicyProvider: categoría de Proveedor
  • IAuthorizationHandlerProvider: procesador de clase proporciona
  • IAuthorizationEvaluator: cheque clase
  • IAuthorizationHandlerContextFactory: factoría de contexto autorización
  • IAuthorizationHandler: procesador de autorización, se inyecta esta colección, una política puede tener licencias de procesador múltiple, seguido de la puesta en práctica
  • clase de configuración: AuthorizationOptions

estilo de nomenclatura de Microsoft es bastante consistente
de servicios:
Proveedor de: ciertos proveedores
Evaluador: comprobación de la clase de tratamiento previo
de fábrica: Fábrica
Handler: Procesador
Contexto: contexto

Mirar el código fuente del proceso, no sólo pueden aprender los principios detrás del marco, también se puede aprender de codificación estilo y el diseño, patrones o bastante útil.

/// <summary>
/// Adds authorization services to the specified <see cref="IServiceCollection" />. 
/// </summary>
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddAuthorizationCore(this IServiceCollection services)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }
    
    services.TryAdd(ServiceDescriptor.Transient<IAuthorizationService, DefaultAuthorizationService>());
    services.TryAdd(ServiceDescriptor.Transient<IAuthorizationPolicyProvider, DefaultAuthorizationPolicyProvider>());
    services.TryAdd(ServiceDescriptor.Transient<IAuthorizationHandlerProvider, DefaultAuthorizationHandlerProvider>());
    services.TryAdd(ServiceDescriptor.Transient<IAuthorizationEvaluator, DefaultAuthorizationEvaluator>());
    services.TryAdd(ServiceDescriptor.Transient<IAuthorizationHandlerContextFactory, DefaultAuthorizationHandlerContextFactory>());
    services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, PassThroughAuthorizationHandler>());
    return services;
}

/// <summary>
/// Adds authorization services to the specified <see cref="IServiceCollection" />. 
/// </summary>
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
/// <param name="configure">An action delegate to configure the provided <see cref="AuthorizationOptions"/>.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddAuthorizationCore(this IServiceCollection services, Action<AuthorizationOptions> configure)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }

    if (configure != null)
    {
        services.Configure(configure);
    }

    return services.AddAuthorizationCore();
}

clase de configuración - AuthorizationOptions

  • PolicyMap: Estrategia y Política de datos del diccionario nombre
  • InvokeHandlersAfterFailure: autorizado procesador es el siguiente disparo después de que el fallo de un procesador, por defecto cierto
  • DefaultPolicy: política predeterminada, RequireAuthenticatedUser construir una estrategia que requiere autenticación de usuario, no permite el acceso anónimo. Ahora una pequeña pista, ¿por qué api un plus [Autorizar], se comprobará la autorización.
  • FallbackPolicy: Pablo en la estrategia final. Sin política se usará cuando la política de garantía mínima. Me siento un poco superflua, que le dio una política por defecto no es así?
  • AddPolicy: add
  • GetPolicy: estrategias de adquisición
/// <summary>
/// Provides programmatic configuration used by <see cref="IAuthorizationService"/> and <see cref="IAuthorizationPolicyProvider"/>.
/// </summary>
public class AuthorizationOptions
{
    private IDictionary<string, AuthorizationPolicy> PolicyMap { get; } = new Dictionary<string, AuthorizationPolicy>(StringComparer.OrdinalIgnoreCase);

    /// <summary>
    /// Determines whether authentication handlers should be invoked after a failure.
    /// Defaults to true.
    /// </summary>
    public bool InvokeHandlersAfterFailure { get; set; } = true;

    /// <summary>
    /// Gets or sets the default authorization policy. Defaults to require authenticated users.
    /// </summary>
    /// <remarks>
    /// The default policy used when evaluating <see cref="IAuthorizeData"/> with no policy name specified.
    /// </remarks>
    public AuthorizationPolicy DefaultPolicy { get; set; } = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();

    /// <summary>
    /// Gets or sets the fallback authorization policy used by <see cref="AuthorizationPolicy.CombineAsync(IAuthorizationPolicyProvider, IEnumerable{IAuthorizeData})"/>
    /// when no IAuthorizeData have been provided. As a result, the AuthorizationMiddleware uses the fallback policy
    /// if there are no <see cref="IAuthorizeData"/> instances for a resource. If a resource has any <see cref="IAuthorizeData"/>
    /// then they are evaluated instead of the fallback policy. By default the fallback policy is null, and usually will have no 
    /// effect unless you have the AuthorizationMiddleware in your pipeline. It is not used in any way by the 
    /// default <see cref="IAuthorizationService"/>.
    /// </summary>
    public AuthorizationPolicy FallbackPolicy { get; set; }

    /// <summary>
    /// Add an authorization policy with the provided name.
    /// </summary>
    /// <param name="name">The name of the policy.</param>
    /// <param name="policy">The authorization policy.</param>
    public void AddPolicy(string name, AuthorizationPolicy policy)
    {
        if (name == null)
        {
            throw new ArgumentNullException(nameof(name));
        }

        if (policy == null)
        {
            throw new ArgumentNullException(nameof(policy));
        }

        PolicyMap[name] = policy;
    }

    /// <summary>
    /// Add a policy that is built from a delegate with the provided name.
    /// </summary>
    /// <param name="name">The name of the policy.</param>
    /// <param name="configurePolicy">The delegate that will be used to build the policy.</param>
    public void AddPolicy(string name, Action<AuthorizationPolicyBuilder> configurePolicy)
    {
        if (name == null)
        {
            throw new ArgumentNullException(nameof(name));
        }

        if (configurePolicy == null)
        {
            throw new ArgumentNullException(nameof(configurePolicy));
        }

        var policyBuilder = new AuthorizationPolicyBuilder();
        configurePolicy(policyBuilder);
        PolicyMap[name] = policyBuilder.Build();
    }

    /// <summary>
    /// Returns the policy for the specified name, or null if a policy with the name does not exist.
    /// </summary>
    /// <param name="name">The name of the policy to return.</param>
    /// <returns>The policy for the specified name, or null if a policy with the name does not exist.</returns>
    public AuthorizationPolicy GetPolicy(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException(nameof(name));
        }

        return PolicyMap.ContainsKey(name) ? PolicyMap[name] : null;
    }
}

Servicio Autorizado - - IAuthorizationService tronco lógica

Interface método define autorización, hay dos de servicio pesado, basado en una requisitos de verificación, que se basa en un policyName cheque.

Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements);

Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName);

lógica de procesamiento de la aplicación por defecto DefaultAuthorizationService facie es bastante simple

  • estrategias de adquisición
  • Obtener condiciones de política de autorización
  • Obtener la autorización contexto
  • Obtiene una colección de procesadores
  • procesador de ejecución de órdenes, almacena el resultado en el contexto
  • contexto de autenticación verificador
  • resultados de la clase de autorización de devolución
 /// <summary>
/// The default implementation of an <see cref="IAuthorizationService"/>.
/// </summary>
public class DefaultAuthorizationService : IAuthorizationService
{
    private readonly AuthorizationOptions _options;
    private readonly IAuthorizationHandlerContextFactory _contextFactory;
    private readonly IAuthorizationHandlerProvider _handlers;
    private readonly IAuthorizationEvaluator _evaluator;
    private readonly IAuthorizationPolicyProvider _policyProvider;
    private readonly ILogger _logger;

    /// <summary>
    /// Creates a new instance of <see cref="DefaultAuthorizationService"/>.
    /// </summary>
    /// <param name="policyProvider">The <see cref="IAuthorizationPolicyProvider"/> used to provide policies.</param>
    /// <param name="handlers">The handlers used to fulfill <see cref="IAuthorizationRequirement"/>s.</param>
    /// <param name="logger">The logger used to log messages, warnings and errors.</param>  
    /// <param name="contextFactory">The <see cref="IAuthorizationHandlerContextFactory"/> used to create the context to handle the authorization.</param>  
    /// <param name="evaluator">The <see cref="IAuthorizationEvaluator"/> used to determine if authorization was successful.</param>  
    /// <param name="options">The <see cref="AuthorizationOptions"/> used.</param>  
    public DefaultAuthorizationService(IAuthorizationPolicyProvider policyProvider, IAuthorizationHandlerProvider handlers, ILogger<DefaultAuthorizationService> logger, IAuthorizationHandlerContextFactory contextFactory, IAuthorizationEvaluator evaluator, IOptions<AuthorizationOptions> options)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }
        if (policyProvider == null)
        {
            throw new ArgumentNullException(nameof(policyProvider));
        }
        if (handlers == null)
        {
            throw new ArgumentNullException(nameof(handlers));
        }
        if (logger == null)
        {
            throw new ArgumentNullException(nameof(logger));
        }
        if (contextFactory == null)
        {
            throw new ArgumentNullException(nameof(contextFactory));
        }
        if (evaluator == null)
        {
            throw new ArgumentNullException(nameof(evaluator));
        }

        _options = options.Value;
        _handlers = handlers;
        _policyProvider = policyProvider;
        _logger = logger;
        _evaluator = evaluator;
        _contextFactory = contextFactory;
    }

    /// <summary>
    /// Checks if a user meets a specific set of requirements for the specified resource.
    /// </summary>
    /// <param name="user">The user to evaluate the requirements against.</param>
    /// <param name="resource">The resource to evaluate the requirements against.</param>
    /// <param name="requirements">The requirements to evaluate.</param>
    /// <returns>
    /// A flag indicating whether authorization has succeeded.
    /// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
    /// </returns>
    public async Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements)
    {
        if (requirements == null)
        {
            throw new ArgumentNullException(nameof(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;
            }
        }

        var result = _evaluator.Evaluate(authContext);
        if (result.Succeeded)
        {
            _logger.UserAuthorizationSucceeded();
        }
        else
        {
            _logger.UserAuthorizationFailed();
        }
        return result;
    }

    /// <summary>
    /// Checks if a user meets a specific authorization policy.
    /// </summary>
    /// <param name="user">The user to check the policy against.</param>
    /// <param name="resource">The resource the policy should be checked with.</param>
    /// <param name="policyName">The name of the policy to check against a specific context.</param>
    /// <returns>
    /// A flag indicating whether authorization has succeeded.
    /// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
    /// </returns>
    public async Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName)
    {
        if (policyName == null)
        {
            throw new ArgumentNullException(nameof(policyName));
        }

        var policy = await _policyProvider.GetPolicyAsync(policyName);
        if (policy == null)
        {
            throw new InvalidOperationException($"No policy found: {policyName}.");
        }
        return await this.AuthorizeAsync(user, resource, policy);
    }
}

Directiva predeterminada - requerir la autenticación de usuarios

La política por defecto para añadir una condición de comprobación DenyAnonymousAuthorizationRequirement

public AuthorizationPolicyBuilder RequireAuthenticatedUser()
{
    Requirements.Add(new DenyAnonymousAuthorizationRequirement());
    return this;
}

La comprobación de si la información de autenticación está presente en el contexto del usuario, la verificación en la verificación de las condiciones en el contexto marcado éxito.

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DenyAnonymousAuthorizationRequirement requirement)
    {
        var user = context.User;
        var userIsAnonymous =
            user?.Identity == null ||
            !user.Identities.Any(i => i.IsAuthenticated);
        if (!userIsAnonymous)
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }

diagrama de temporización de Autorización

proyecto de autorización se entiende bastante bien, Microsoft proporciona un modelo de autorización basada en políticas, la mayor parte del código o negocio específico necesita su propia lograr.

clase diagrama de clases AuthorizationPolicy {} Requisitos Requisito clase {} {} AuthorizationHandler clase clase IAuthorizationHandler {+ HandleAsync (contexto AuthorizationHandlerContext)}} {clase IAuthorizationRequirement Requisito -> AuthorizationHandler AuthorizationHandler -> IAuthorizationHandler Requisito -> IAuthorizationHandler Requisito -> IAuthorizationRequirement

Middleware ir?

Desarrollo sin necesidad de escribir código como UseAuthorization, el proyecto no encuentra el middleware, ni siquiera puede encontrar un lugar para utilizar AuthorizeAttribute. Entonces la pregunta es, cómo un método conocido marco de etiquetar el atributo [Autorizar], y luego se realiza una suma de comprobación de la misma?

La respuesta es el procesado de cuadro Mvc, lee los nodos de [la Authorize] y [los AllowAnonymous] características, y la lógica de disparo. Mvc no dio detalles sobre el aspecto lata interesados en el código fuente.
AspNetCore \ src \ MVC \ Mvc.Core \ src \ ApplicationModels \ AuthorizationApplicationModelProvider.cs.

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<IAuthorizeData>().ToArray();
        if (controllerModelAuthData.Length > 0)
        {
            controllerModel.Filters.Add(GetFilter(_policyProvider, controllerModelAuthData));
        }
        foreach (var attribute in controllerModel.Attributes.OfType<IAllowAnonymous>())
        {
            controllerModel.Filters.Add(new AllowAnonymousFilter());
        }

        foreach (var actionModel in controllerModel.Actions)
        {
            var actionModelAuthData = actionModel.Attributes.OfType<IAuthorizeData>().ToArray();
            if (actionModelAuthData.Length > 0)
            {
                actionModel.Filters.Add(GetFilter(_policyProvider, actionModelAuthData));
            }

            foreach (var attribute in actionModel.Attributes.OfType<IAllowAnonymous>())
            {
                actionModel.Filters.Add(new AllowAnonymousFilter());
            }
        }
    }
}

Supongo que te gusta

Origin www.cnblogs.com/holdengong/p/12575914.html
Recomendado
Clasificación