Registre la autenticación y autorización del núcleo de asp.net como un todo

En el proceso de usar asp.net core para desarrollar un sistema de aplicación, la autenticación de la identidad del usuario y el control de acceso de autorización están básicamente involucrados. Por lo tanto, también es muy importante comprender el proceso de autenticación y autorización. A continuación se analiza la autenticación y autorización. en el marco principal de asp.net Código fuente para analizar los principios de autenticación y autorización y la relación entre autenticación y autorización.

¿Qué es la certificación?

La autenticación es un proceso para que el sistema de la aplicación identifique la identidad del visitante actual. Cuando el sistema de la aplicación recibe la solicitud del navegador, generalmente identifica la identidad del usuario que ha iniciado sesión actualmente de acuerdo con alguna información clave del usuario que se encuentra en la solicitud. Al analizar la información, para verificar la validez del usuario y descifrarla. Si se pasa la verificación, significa que se pasó la autenticación. El sistema de la aplicación almacenará la información del usuario autenticado en el contexto de la solicitud Http para negocios posteriores proceso de uso y autorización.

En asp.net core, la información de autenticación generalmente se cifra y almacena en una cookie, y la información de la cookie se envía al sistema de la aplicación cada vez que se accede a una página que requiere autenticación, de modo que el sistema de la aplicación pueda identificar la identidad del visitante. que es la clásica autenticación de cookies.

Cabe señalar que la autenticación solo identifica la identidad del usuario de acceso actual y no es responsable de la lógica de control de acceso específica. Si no tiene acceso a un recurso, devuelva 403 y devuelva 401 si no ha iniciado sesión. Todos estos están controlados por el proceso de autorización.

El middleware responsable del proceso de autenticación en asp.net core es la clase AuthenticationMiddleware . El siguiente es el código fuente de asp.net core 3.1. Como puede ver, primero recorra todos los esquemas de autenticación que implementan la interfaz IAuthenticationRequestHandler y llame al Método HandleRequestAsync de la interfaz IAuthenticationRequestHandler. Si se pasa la autenticación, no continuará ejecutándose, y en este momento HttpContext.User ya contiene la información del usuario autenticado. Si todos los esquemas de autenticación que implementan la interfaz IAuthenticationRequestHandler no logran autenticar el  acceso  actual usuario, se utilizará la autenticación predeterminada Esquema para la autenticación (es decir: el esquema de autenticación devuelto por GetDefaultAuthenticateSchemeAsync ), puede ver que incluso si el proceso de autenticación no logra identificar la identidad del usuario del visitante actual, continuará ejecutando el siguiente proceso (cola: espera _next (contexto); )

public class AuthenticationMiddleware
{
	private readonly RequestDelegate _next;

	public IAuthenticationSchemeProvider Schemes
	{
		get;
		set;
	}

	public AuthenticationMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
	{
		if (next == null)
		{
			throw new ArgumentNullException("next");
		}
		if (schemes == null)
		{
			throw new ArgumentNullException("schemes");
		}
		_next = next;
		Schemes = schemes;
	}

	public async Task Invoke(HttpContext context)
	{
		context.Features.Set((IAuthenticationFeature)new AuthenticationFeature
		{
			OriginalPath = context.Request.Path,
			OriginalPathBase = context.Request.PathBase
		});
		IAuthenticationHandlerProvider handlers = 
                          context.RequestServices.
                          GetRequiredService<IAuthenticationHandlerProvider>();
		foreach (AuthenticationScheme item in await Schemes.GetRequestHandlerSchemesAsync())
		{
			IAuthenticationRequestHandler authenticationRequestHandler = 
                                                (await handlers.
                                                GetHandlerAsync(context, item.Name))
                                                 as IAuthenticationRequestHandler;
			bool flag = authenticationRequestHandler != null;
			if (flag)
			{
				flag = await authenticationRequestHandler.HandleRequestAsync();
			}
			if (flag)
			{
				return;
			}
		}
                
		AuthenticationScheme authenticationScheme = 
                                        await Schemes.
                                              GetDefaultAuthenticateSchemeAsync();
		if (authenticationScheme != null)
		{
                        //内部调用IAuthenticationService进行认证。
			AuthenticateResult authenticateResult = 
                                     await context.
                                     AuthenticateAsync(authenticationScheme.Name);
			if (authenticateResult?.Principal != null)
			{
				context.User = authenticateResult.Principal;
			}
		}
		await _next(context);
	}
}

¿Qué es la autorización?

La autorización es el proceso de determinar si el usuario de acceso actual tiene acceso a un determinado recurso del sistema. Para los recursos del sistema que requieren autorización para acceder, generalmente se identifican mediante la función [Autorizar] . A través de esta función, puede especificar qué rol de usuario requiere un recurso para acceder. ¿Qué política de autorización se debe cumplir para acceder y cuál es el esquema de autenticación de usuario utilizado al acceder a este recurso? Cuando un usuario accede a una API o página del sistema, el proceso de autorización verificará si el usuario actual tiene acceso a la API o página. Si falla la verificación de autorización, se juzgará si el usuario actual ha pasado la autenticación. Si la autenticación pasa, pero no hay permiso para acceder al recurso, entonces devuelve 403 (prohibido), si no está autenticado , luego devuelva directamente 401 (sin autenticar), lo que indica que se requiere el usuario Al acceder después de la autenticación de inicio de sesión, se debe tener en cuenta que la autenticación de la identidad del usuario se realizará antes de verificar si la autoridad de acceso está disponible. depende de si AuthorizeAttribute especifica un esquema de autenticación específico. De lo contrario, el proceso de autenticación se adoptará directamente. La información de identidad de la autenticación exitosa.

En asp.net core, el proceso de autorización se ejecuta a través de la clase AuthorizationMiddleware.El siguiente es el código fuente en asp.net core 3.1.

public class AuthenticationMiddleware
{
	private readonly RequestDelegate _next;

	public IAuthenticationSchemeProvider Schemes
	{
		get;
		set;
	}

	public AuthenticationMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
	{
		if (next == null)
		{
			throw new ArgumentNullException("next");
		}
		if (schemes == null)
		{
			throw new ArgumentNullException("schemes");
		}
		_next = next;
		Schemes = schemes;
	}

	public async Task Invoke(HttpContext context)
	{
		context.Features.Set((IAuthenticationFeature)new AuthenticationFeature
		{
			OriginalPath = context.Request.Path,
			OriginalPathBase = context.Request.PathBase
		});
		IAuthenticationHandlerProvider handlers =             
                   context.RequestServices.
                   GetRequiredService<IAuthenticationHandlerProvider>();
		foreach (AuthenticationScheme item in await Schemes.GetRequestHandlerSchemesAsync())
		{
			IAuthenticationRequestHandler authenticationRequestHandler = 
                    (await handlers.GetHandlerAsync(context, item.Name))
                     as IAuthenticationRequestHandler;
			bool flag = authenticationRequestHandler != null;
			if (flag)
			{
				flag = await authenticationRequestHandler.HandleRequestAsync();
			}
			if (flag)
			{
				return;
			}
		}
                
		AuthenticationScheme authenticationScheme = await Schemes.GetDefaultAuthenticateSchemeAsync();
		if (authenticationScheme != null)
		{
             //内部调用IAuthenticationService进行认证。
			AuthenticateResult authenticateResult = await context.AuthenticateAsync(authenticationScheme.Name);
			if (authenticateResult?.Principal != null)
			{
				context.User = authenticateResult.Principal;
			}
		}
		await _next(context);
	}
}

La clase de implementación de la interfaz IPolicyEvaluator El código de la clase PolicyEvaluator es el siguiente, esta clase es principalmente responsable de la autenticación y autorización en el proceso de autorización.

// Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Internal;

public class PolicyEvaluator : IPolicyEvaluator
{
	private readonly IAuthorizationService _authorization;

	public PolicyEvaluator(IAuthorizationService authorization)
	{
		_authorization = authorization;
	}

	public virtual async Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
	{
             //这里去判断当前资源是否有要求特定的认证方案进行认证,如果有指定特定的认证方案
             //则分别对每个认证方案进行认证,并把认证后的用户信息进行合并
             //最终存储到HttpContext.User属性中,并返回认证成功,如果没有指定认证方案
             //则使用认证流程中已经认证的用户信息作为认证结果返回,
            //从这里可以看出,认证流程还是很有必要的,在资源没有指定认证方案的前提下
            //认证流程为授权流程提供当前访问者的身份信息
            //以便执行是否具备相应资源的访问权限检查
            //否则就直接进入Challenge流程将要求用户先进行身份认证了
		if (policy.AuthenticationSchemes != null && policy.AuthenticationSchemes.Count > 0)
		{
			ClaimsPrincipal newPrincipal = null;
			foreach (string authenticationScheme in policy.AuthenticationSchemes)
			{
				AuthenticateResult authenticateResult = await context.AuthenticateAsync(authenticationScheme);
				if (authenticateResult != null && authenticateResult.Succeeded)
				{
					newPrincipal = SecurityHelper.MergeUserPrincipal(newPrincipal, authenticateResult.Principal);
				}
			}
			if (newPrincipal != null)
			{
				context.User = newPrincipal;
				return AuthenticateResult.Success(new AuthenticationTicket(newPrincipal, string.Join(";", policy.AuthenticationSchemes)));
			}
			context.User = new ClaimsPrincipal(new ClaimsIdentity());
			return AuthenticateResult.NoResult();
		}
		return (context.User?.Identity?.IsAuthenticated).GetValueOrDefault() ? AuthenticateResult.Success(new AuthenticationTicket(context.User, "context.User")) : AuthenticateResult.NoResult();
	}
        //resource为EndPoint对象。
	public virtual async Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context, object resource)
	{
		if (policy == null)
		{
			throw new ArgumentNullException("policy");
		}
                //这里调用IAuthorizationService.AuthorizeAsync方法进行授权检查
                //默认实现类为:DefaultAuthorizationService。
		if ((await _authorization.AuthorizeAsync(context.User, resource, policy)).Succeeded)
		{
			return PolicyAuthorizationResult.Success();
		}
                //下面这句表示如果授权检查失败的情况下是进入Forbid流程还是进入Challenge流程
                //可以看到如果认证成功,那么表示无权限访问进入Forbid流程。
                //如果未认证,则进入Challenge流程,引导用户登录认证。
		return authenticationResult.Succeeded ? PolicyAuthorizationResult.Forbid() : PolicyAuthorizationResult.Challenge();
	}
}

¿Cuál es la relación entre autenticación y autorización?

Antes de la verificación de autorización, primero se realizará la autenticación de la identidad del usuario, pero el proceso de autenticación aquí solo se ejecutará cuando el recurso al que se accede tenga un esquema de autenticación específico especificado; de lo contrario, la información de autenticación generada en el proceso de autenticación unificado se utilizará directamente.

Se puede entender que el proceso de autenticación es decirle al sistema de aplicación la identidad del visitante actual por un lado y por otro lado identificar la información de identidad del usuario para la verificación de autorización Cuando el recurso no especifica qué esquema de autenticación para usar, el proceso de autorización utilizará la autenticación unificada. Si la información del usuario generada por la autenticación en el proceso no está habilitada, y el recurso al que se accede no especifica un esquema de autenticación específico para autenticar la identidad del visitante, aún será Se requiere iniciar sesión para la autenticación al acceder al recurso. Por lo tanto, otro propósito del proceso de autenticación es proporcionar información de autenticación de usuario predeterminada para el proceso de autorización.

En resumen,

El proceso de autenticación tiene principalmente las siguientes funciones:

  1. Identifique la información de identidad de los visitantes del sistema y proporciónela para uso comercial posterior después de pasar la autenticación.
  2. Proporcione información de identidad del usuario al proceso de autorización (cuando el recurso no especifica un esquema de autenticación específico, use el esquema de autenticación predeterminado para autenticar la información del usuario).
  3. Implemente la lógica de procesamiento después de una falla de autorización, como 401 (no autenticado) y 403 (acceso prohibido) devueltos después de que falle la verificación de autorización, finalmente procesados ​​por el método ChallengeAsync y el método ForbidAsync del esquema de autenticación. Estos métodos se definen en IAuthenticationHandler. El proceso de autorización llama al proceso cuando el error de autorización es 401/403.

El proceso de autorización tiene principalmente las siguientes funciones:

  1. El proceso de autorización es principalmente para verificar si el usuario actual tiene derechos de acceso a los recursos especificados. Si la verificación de autorización falla, como 401 (no autenticado) y 403 (prohibido), entonces se llamará a los métodos ChallengeAsync y ForbidAsync del esquema de autenticación. respectivamente, es decir , el proceso de autorización se enfoca en el control del proceso luego de que falla la autorización.
  2. Otra tarea principal del proceso de autorización es verificar si las políticas de autorización se pueden verificar. Si un recurso especifica una o más políticas de autorización a través del atributo Política de AuthorizeAttribute, entonces todas las políticas de autorización deben verificarse para que se consideren exitosas. Si no se especifica Autorización estrategia, luego verifique si la estrategia de autorización predeterminada puede pasar la prueba, la estrategia de autorización predeterminada es requerir que el usuario pase la autenticación antes de permitir el acceso a los recursos.

El proceso de autorización básicamente atraviesa todos los IAuthorizationHandlers inyectados en el contenedor ( Microsoft inyecta en el contenedor de manera predeterminada cuando AddAuthorization: PassThroughAuthorizationHandler, este controlador de autorización atraviesa todas las clases de requisitos que implementan IAuthorizationHandler en AuthorizationHandlerContext.Requirements, y llama a su método HandleAsync para verificar si el actual El requisito puede pasar la verificación ) y verificar los requisitos contenidos en todas las políticas que deben cumplirse para acceder a los recursos especificados. Si se verifican todos los requisitos contenidos en las políticas, entonces la autorización es exitosa. El requisito aquí se refiere a la implementación de IAuthorizationRequirement La clase, esta interfaz es una interfaz vacía, utilizada para marcar el requisito.

Supongo que te gusta

Origin blog.csdn.net/qq_41872328/article/details/126834499
Recomendado
Clasificación