AspNetCore3.1_Secutiry _3_Authentication_Cookies análisis sintáctico fuente


Título: "AspNetCore3.1_Secutiry源码解析_3_Authentication_Cookies"
Fecha: 2020-03-19T22: 52: 39 + 08: 00
proyecto: falsa
---

Serie de directorio de artículos

inyección de dependencia

AuthenticationBuilder AddCookie(this AuthenticationBuilder builder);

AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme);

AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, Action<CookieAuthenticationOptions> configureOptions);

Proporciona varias sobrecargas, utilice la configuración por defecto, o modificar los valores de configuración de clases CookieAuthenticationOptions por delegación.

Se puede definir conexión, desconexión, se negó a hacer frente a la página de inicio de sesión, el tiempo de caducidad de cookies, las diversas etapas de los eventos del ciclo de vida.


diagrama de clases
CookieAuthenticationOptions clase {
CookieBuilder Cookies
IDataProtectionProvider DataProtectionProvider
bool SlidingExpiration
PathString LoginPath
PathString LogoutPath
PathString AccessDeniedPath
CookieAuthenticationEvents Eventos
ISecureDataFormat TicketDataFormat
ITicketStore SessionStore
TimeSpan ExpireTimeSpan
}
AuthenticationSchemeOptions clase {
cadena ClaimsIssuer
objeto eventos
Tipo EventsType
cadena ForwardDefault
cadena ForwardAuthenticate
cadena ForwardChallenge
cadena ForwardForbid
ForwardSignIn cadena de
cadena ForwardSignOut
Func ForwardDefaultSelector
}
CookieAuthenticationOptions -> AuthenticationSchemeOptions

Si no se define la configuración, la configuración por defecto será utilizado como CookieAuthenticationDefaults definidos

 /// <summary>
    /// Default values related to cookie-based authentication handler
    /// </summary>
    public static class CookieAuthenticationDefaults
    {
        /// <summary>
        /// The default value used for CookieAuthenticationOptions.AuthenticationScheme
        /// </summary>
        public const string AuthenticationScheme = "Cookies";

        /// <summary>
        /// The prefix used to provide a default CookieAuthenticationOptions.CookieName
        /// </summary>
        public static readonly string CookiePrefix = ".AspNetCore.";

        /// <summary>
        /// The default value used by CookieAuthenticationMiddleware for the
        /// CookieAuthenticationOptions.LoginPath
        /// </summary>
        public static readonly PathString LoginPath = new PathString("/Account/Login");

        /// <summary>
        /// The default value used by CookieAuthenticationMiddleware for the
        /// CookieAuthenticationOptions.LogoutPath
        /// </summary>
        public static readonly PathString LogoutPath = new PathString("/Account/Logout");

        /// <summary>
        /// The default value used by CookieAuthenticationMiddleware for the
        /// CookieAuthenticationOptions.AccessDeniedPath
        /// </summary>
        public static readonly PathString AccessDeniedPath = new PathString("/Account/AccessDenied");

        /// <summary>
        /// The default value of the CookieAuthenticationOptions.ReturnUrlParameter
        /// </summary>
        public static readonly string ReturnUrlParameter = "ReturnUrl";
    }

Registro esquema CookieAuthenticationHandler clase de procesador

estructura procesador Clase

La lógica es la columna vertebral de las capas de la herencia de lograr, principal método CookieAuthenticationHandler es reescribir la certificación de la acción de la clase padre de cinco manija para lograr su propia lógica de procesamiento.

clase diagrama de clases CookieAuthenticationHandler {HandleAuthenticateAsync () HandleSignInAsync () HandleSignOutAsync () HandleForbiddenAsync () HandleChallengeAsync () FinishResponseAsync ()} clase SignInAuthenticationHandler {SignInAsync () HandleSignInAsync ()} clase IAuthenticationSignInHandler {SignIn () HandleSignIn ()} clase SignOutAuthenticationHandler {SignOutAsync () HandleSignOutAsync ()} {clase IAuthenticationSignOutHandler SighOut (HandleSignOut) ()} {clase AuthenticationHandler AuthenticationScheme esquema TOptions Opciones HttpContext Contexto HttpRequest Solicitar HttpResponse de respuesta PathString OriginalPath PathString OriginalPathBase ILogger Logger URLEncoder URLEncoder ISystemClock Reloj cadena ClaimsIssuer objeto Eventos cadena CurrentUri + Tarea InitializeAsync (esquema AuthenticationScheme,HttpContext contexto) + Tarea AuthenticateAsync () + Tarea ChallengeAsync (AuthenticationProperties propiedades) + Tarea ForbidAsync (AuthenticationProperties propiedades)} {clase IAuthenticationHandler HandleAsync ()} CookieAuthenticationHandler -> SignInAuthenticationHandler SignInAuthenticationHandler -> IAuthenticationSignInHandler SignInAuthenticationHandler -> SignOutAuthenticationHandler SignOutAuthenticationHandler -> IAuthenticationSignOutHandler SignOutAuthenticationHandler -> AuthenticationHandler AuthenticationHandler -> IAuthenticationHandlerIAuthenticationSignInHandler SignInAuthenticationHandler -> SignOutAuthenticationHandler SignOutAuthenticationHandler -> IAuthenticationSignOutHandler SignOutAuthenticationHandler -> AuthenticationHandler AuthenticationHandler -> IAuthenticationHandlerIAuthenticationSignInHandler SignInAuthenticationHandler -> SignOutAuthenticationHandler SignOutAuthenticationHandler -> IAuthenticationSignOutHandler SignOutAuthenticationHandler -> AuthenticationHandler AuthenticationHandler -> IAuthenticationHandler

procesador detallada clase

HandleSignInAsync - inicio de sesión

  1. Después de que el lado del negocio después de completar la verificación del usuario, los objetos de entrada construidos método ClaimsPrincipal SignIn, si el usuario es nulo o se produce una excepción
  2. IssuedUtc Si no se especifica, entonces la hora actual, la fecha de caducidad ExpiresUtc si el tiempo de expiración no especificado se calcula IssuedUtc y ExpireTimeSpan
  3. evento de disparo SigningIn
  4. credenciales de construcción AuthenticationTicket
  5. Si SessionStore no es nulo, la información de vales en SessionStore
  6. TicketDataFormat para cifrar el vale
  7. CookieManager escribe información de las cookies t cifrada
  8. evento de disparo SignedIn
  9. Si hay un valor y es igual OriginalPath LoginPath, la necesidad de saltar, salto en dirección Properties.RedirectUri
protected async override Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
    {
        if (user == null)
        {
            throw new ArgumentNullException(nameof(user));
        }

        properties = properties ?? new AuthenticationProperties();

        _signInCalled = true;

        // Process the request cookie to initialize members like _sessionKey.
        await EnsureCookieTicket();
        var cookieOptions = BuildCookieOptions();

        var signInContext = new CookieSigningInContext(
            Context,
            Scheme,
            Options,
            user,
            properties,
            cookieOptions);

        DateTimeOffset issuedUtc;
        if (signInContext.Properties.IssuedUtc.HasValue)
        {
            issuedUtc = signInContext.Properties.IssuedUtc.Value;
        }
        else
        {
            issuedUtc = Clock.UtcNow;
            signInContext.Properties.IssuedUtc = issuedUtc;
        }

        if (!signInContext.Properties.ExpiresUtc.HasValue)
        {
            signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
        }

        await Events.SigningIn(signInContext);

        if (signInContext.Properties.IsPersistent)
        {
            var expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan);
            signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime();
        }

        var ticket = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.Scheme.Name);

        if (Options.SessionStore != null)
        {
            if (_sessionKey != null)
            {
                await Options.SessionStore.RemoveAsync(_sessionKey);
            }
            _sessionKey = await Options.SessionStore.StoreAsync(ticket);
            var principal = new ClaimsPrincipal(
                new ClaimsIdentity(
                    new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
                    Options.ClaimsIssuer));
            ticket = new AuthenticationTicket(principal, null, Scheme.Name);
        }

        var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());

        Options.CookieManager.AppendResponseCookie(
            Context,
            Options.Cookie.Name,
            cookieValue,
            signInContext.CookieOptions);

        var signedInContext = new CookieSignedInContext(
            Context,
            Scheme,
            signInContext.Principal,
            signInContext.Properties,
            Options);

        await Events.SignedIn(signedInContext);

        // Only redirect on the login path
        var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath;
        await ApplyHeaders(shouldRedirect, signedInContext.Properties);

        Logger.AuthenticationSchemeSignedIn(Scheme.Name);
    }

HandleAuthentication - proceso de certificación

  1. Cookie se lee en el documento: La primera clase de galletas TicketDataFormat decodificado SessionStore si no es nulo, el valor se decodifica describe sólo la clave de sesión, recuperar los valores de la SessionStore.
  2. Construcción de CookieValidatePrincipalContext, evento de disparo ValidatePrincipal
  3. Si ShouldRenew mordió verdad, se actualizará la cookie (por defecto ShoudRenew es falsa, puede ser modificada por suscripción eventos ValidatePrincipal)
  4. Autentificación, comprobantes de pago AuthenticationTicket, incluyendo context.Principal, context.Properties, información Scheme.Name
 protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    var result = await EnsureCookieTicket();
    if (!result.Succeeded)
    {
        return result;
    }

    var context = new CookieValidatePrincipalContext(Context, Scheme, Options, result.Ticket);
    await Events.ValidatePrincipal(context);

    if (context.Principal == null)
    {
        return AuthenticateResult.Fail("No principal.");
    }

    if (context.ShouldRenew)
    {
        RequestRefresh(result.Ticket, context.Principal);
    }

    return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
}

HandleSignOutAsync - proceso de cierre de sesión

  1. La adquisición de Credenciales
  2. SessionStore no es nulo, a continuación, retire de la sesión SessionStore
  3. evento de disparo SigningOut
  4. CookieManager eliminar la cookie
  5. Si la dirección de origen es LogoutPath, saltar a la dirección después del cierre de sesión
protected async override Task HandleSignOutAsync(AuthenticationProperties properties)
    {
        properties = properties ?? new AuthenticationProperties();

        _signOutCalled = true;

        // Process the request cookie to initialize members like _sessionKey.
        await EnsureCookieTicket();
        var cookieOptions = BuildCookieOptions();
        if (Options.SessionStore != null && _sessionKey != null)
        {
            await Options.SessionStore.RemoveAsync(_sessionKey);
        }

        var context = new CookieSigningOutContext(
            Context,
            Scheme,
            Options,
            properties,
            cookieOptions);

        await Events.SigningOut(context);

        Options.CookieManager.DeleteCookie(
            Context,
            Options.Cookie.Name,
            context.CookieOptions);

        // Only redirect on the logout path
        var shouldRedirect = Options.LogoutPath.HasValue && OriginalPath == Options.LogoutPath;
        await ApplyHeaders(shouldRedirect, context.Properties);

        Logger.AuthenticationSchemeSignedOut(Scheme.Name);
    }

HandleForbidAsync - prohibir el acceso al tratamiento

Si se trata de solicitud de devolución ajax un código de estado 403, si no, vaya a la configuración de AccessDeniedPath

 protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
{
    var returnUrl = properties.RedirectUri;
    if (string.IsNullOrEmpty(returnUrl))
    {
        returnUrl = OriginalPathBase + OriginalPath + Request.QueryString;
    }
    var accessDeniedUri = Options.AccessDeniedPath + QueryString.Create(Options.ReturnUrlParameter, returnUrl);
    var redirectContext = new RedirectContext<CookieAuthenticationOptions>(Context, Scheme, Options, properties, BuildRedirectUri(accessDeniedUri));
    await Events.RedirectToAccessDenied(redirectContext);
}

public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToAccessDenied { get; set; } = context =>
    {
        if (IsAjaxRequest(context.Request))
        {
            context.Response.Headers[HeaderNames.Location] = context.RedirectUri;
            context.Response.StatusCode = 403;
        }
        else
        {
            context.Response.Redirect(context.RedirectUri);
        }
        return Task.CompletedTask;
    };

otro

ICookieManager - gestión de cookies

La implementación por defecto es ChunkingCookieManager, si la cookie es demasiado largo, la clase se dividirá la cookie poco pas trozo.

 /// <summary>
/// This is used by the CookieAuthenticationMiddleware to process request and response cookies.
/// It is abstracted from the normal cookie APIs to allow for complex operations like chunking.
/// </summary>
public interface ICookieManager
{
    /// <summary>
    /// Retrieve a cookie of the given name from the request.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    string GetRequestCookie(HttpContext context, string key);

    /// <summary>
    /// Append the given cookie to the response.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="options"></param>
    void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options);

    /// <summary>
    /// Append a delete cookie to the response.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="key"></param>
    /// <param name="options"></param>
    void DeleteCookie(HttpContext context, string key, CookieOptions options);
}

ITicketStore - para lograr la galleta Persistencia

no se logra por defecto ITicketStore, si es que implementa esta interfaz e inyectar, que pueden ser cookie persistente, por lo que se expone a que el navegador es sólo una cookie-id.

/// <summary>
/// This provides an abstract storage mechanic to preserve identity information on the server
/// while only sending a simple identifier key to the client. This is most commonly used to mitigate
/// issues with serializing large identities into cookies.
/// </summary>
public interface ITicketStore
{
    /// <summary>
    /// Store the identity ticket and return the associated key.
    /// </summary>
    /// <param name="ticket">The identity information to store.</param>
    /// <returns>The key that can be used to retrieve the identity later.</returns>
    Task<string> StoreAsync(AuthenticationTicket ticket);

    /// <summary>
    /// Tells the store that the given identity should be updated.
    /// </summary>
    /// <param name="key"></param>
    /// <param name="ticket"></param>
    /// <returns></returns>
    Task RenewAsync(string key, AuthenticationTicket ticket);

    /// <summary>
    /// Retrieves an identity from the store for the given key.
    /// </summary>
    /// <param name="key">The key associated with the identity.</param>
    /// <returns>The identity associated with the given key, or if not found.</returns>
    Task<AuthenticationTicket> RetrieveAsync(string key);

    /// <summary>
    /// Remove the identity associated with the given key.
    /// </summary>
    /// <param name="key">The key associated with the identity.</param>
    /// <returns></returns>
    Task RemoveAsync(string key);
}

Supongo que te gusta

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