1.5AuthenticateResult--【AuthenticateResult->AuthenticationTicket->AuthenticationProperties】

AuthenticateResult->AuthenticationTicket->AuthenticationProperties->ClaimsPrincipal

using System;
using System.Diagnostics.CodeAnalysis;
using System.Security.Claims;

namespace Microsoft.AspNetCore.Authentication
{
    /// <summary>
    /// Contains the result of an Authenticate call
    /// </summary>
    public class AuthenticateResult
    {
        /// <summary>
        /// Creates a new <see cref="AuthenticateResult"/> instance.
        /// </summary>
        protected AuthenticateResult() { }

        /// <summary>
        /// If a ticket was produced, authenticate was successful.
        /// </summary>
        [MemberNotNullWhen(true, nameof(Ticket), nameof(Principal), nameof(Properties))]
        public bool Succeeded => Ticket != null;

        /// <summary>
        /// The authentication ticket.
        /// </summary>
        public AuthenticationTicket? Ticket { get; protected set; }

        /// <summary>
        /// Gets the claims-principal with authenticated user identities.
        /// </summary>
        public ClaimsPrincipal? Principal => Ticket?.Principal;

        /// <summary>
        /// Additional state values for the authentication session.
        /// </summary>
        public AuthenticationProperties? Properties { get; protected set; }

        /// <summary>
        /// Holds failure information from the authentication.
        /// </summary>
        public Exception? Failure { get; protected set; }

        /// <summary>
        /// Indicates that there was no information returned for this authentication scheme.
        /// </summary>
        public bool None { get; protected set; }

        /// <summary>
        /// Create a new deep copy of the result
        /// </summary>
        /// <returns>A copy of the result</returns>
        public AuthenticateResult Clone()
        {
            if (None)
            {
                return NoResult();
            }
            if (Failure != null)
            {
                return Fail(Failure, Properties?.Clone());
            }
            if (Succeeded)
            {
                return Success(Ticket!.Clone());
            }
            // This shouldn't happen
            throw new NotImplementedException();
        }

        /// <summary>
        /// Indicates that authentication was successful.
        /// </summary>
        /// <param name="ticket">The ticket representing the authentication result.</param>
        /// <returns>The result.</returns>
        public static AuthenticateResult Success(AuthenticationTicket ticket)
        {
            if (ticket == null)
            {
                throw new ArgumentNullException(nameof(ticket));
            }
            return new AuthenticateResult() { Ticket = ticket, Properties = ticket.Properties };
        }

        /// <summary>
        /// Indicates that there was no information returned for this authentication scheme.
        /// </summary>
        /// <returns>The result.</returns>
        public static AuthenticateResult NoResult()
        {
            return new AuthenticateResult() { None = true };
        }

        /// <summary>
        /// Indicates that there was a failure during authentication.
        /// </summary>
        /// <param name="failure">The failure exception.</param>
        /// <returns>The result.</returns>
        public static AuthenticateResult Fail(Exception failure)
        {
            return new AuthenticateResult() { Failure = failure };
        }

        /// <summary>
        /// Indicates that there was a failure during authentication.
        /// </summary>
        /// <param name="failure">The failure exception.</param>
        /// <param name="properties">Additional state values for the authentication session.</param>
        /// <returns>The result.</returns>
        public static AuthenticateResult Fail(Exception failure, AuthenticationProperties? properties)
        {
            return new AuthenticateResult() { Failure = failure, Properties = properties };
        }

        /// <summary>
        /// Indicates that there was a failure during authentication.
        /// </summary>
        /// <param name="failureMessage">The failure message.</param>
        /// <returns>The result.</returns>
        public static AuthenticateResult Fail(string failureMessage)
            => Fail(new Exception(failureMessage));

        /// <summary>
        /// Indicates that there was a failure during authentication.
        /// </summary>
        /// <param name="failureMessage">The failure message.</param>
        /// <param name="properties">Additional state values for the authentication session.</param>
        /// <returns>The result.</returns>
        public static AuthenticateResult Fail(string failureMessage, AuthenticationProperties? properties)
            => Fail(new Exception(failureMessage), properties);
    }
}
using System;
using System.Security.Claims;

namespace Microsoft.AspNetCore.Authentication
{
    /// <summary>
    /// Contains user identity information as well as additional authentication state.
    /// </summary>
    public class AuthenticationTicket
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationTicket"/> class
        /// </summary>
        /// <param name="principal">the <see cref="ClaimsPrincipal"/> that represents the authenticated user.</param>
        /// <param name="properties">additional properties that can be consumed by the user or runtime.</param>
        /// <param name="authenticationScheme">the authentication scheme that was responsible for this ticket.</param>
        public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties? properties, string authenticationScheme)
        {
            if (principal == null)
            {
                throw new ArgumentNullException(nameof(principal));
            }

            AuthenticationScheme = authenticationScheme;
            Principal = principal;
            Properties = properties ?? new AuthenticationProperties();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationTicket"/> class
        /// </summary>
        /// <param name="principal">the <see cref="ClaimsPrincipal"/> that represents the authenticated user.</param>
        /// <param name="authenticationScheme">the authentication scheme that was responsible for this ticket.</param>
        public AuthenticationTicket(ClaimsPrincipal principal, string authenticationScheme)
            : this(principal, properties: null, authenticationScheme: authenticationScheme)
        { }

        /// <summary>
        /// Gets the authentication scheme that was responsible for this ticket.
        /// </summary>
        public string AuthenticationScheme { get; }

        /// <summary>
        /// Gets the claims-principal with authenticated user identities.
        /// </summary>
        public ClaimsPrincipal Principal { get; }

        /// <summary>
        /// Additional state values for the authentication session.
        /// </summary>
        public AuthenticationProperties Properties { get; }

        /// <summary>
        /// Returns a copy of the ticket.
        /// </summary>
        /// <remarks>
        /// The method clones the <see cref="Principal"/> by calling <see cref="ClaimsIdentity.Clone"/> on each of the <see cref="ClaimsPrincipal.Identities"/>.
        /// </remarks>
        /// <returns>A copy of the ticket</returns>
        public AuthenticationTicket Clone()
        {
            var principal = new ClaimsPrincipal();
            foreach (var identity in Principal.Identities)
            {
                principal.AddIdentity(identity.Clone());
            }
            return new AuthenticationTicket(principal, Properties.Clone(), AuthenticationScheme);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json.Serialization;

namespace Microsoft.AspNetCore.Authentication
{
    /// <summary>
    /// Dictionary used to store state values about the authentication session.
    /// </summary>
    public class AuthenticationProperties
    {
        internal const string IssuedUtcKey = ".issued";
        internal const string ExpiresUtcKey = ".expires";
        internal const string IsPersistentKey = ".persistent";
        internal const string RedirectUriKey = ".redirect";
        internal const string RefreshKey = ".refresh";
        internal const string UtcDateTimeFormat = "r";

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationProperties"/> class.
        /// </summary>
        public AuthenticationProperties()
            : this(items: null, parameters: null)
        { }

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationProperties"/> class.
        /// </summary>
        /// <param name="items">State values dictionary to use.</param>
        [JsonConstructor]
        public AuthenticationProperties(IDictionary<string, string?> items)
            : this(items, parameters: null)
        { }

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationProperties"/> class.
        /// </summary>
        /// <param name="items">State values dictionary to use.</param>
        /// <param name="parameters">Parameters dictionary to use.</param>
        public AuthenticationProperties(IDictionary<string, string?>? items, IDictionary<string, object?>? parameters)
        {
            Items = items ?? new Dictionary<string, string?>(StringComparer.Ordinal);
            Parameters = parameters ?? new Dictionary<string, object?>(StringComparer.Ordinal);
        }

        /// <summary>
        /// Return a copy.
        /// </summary>
        /// <returns>A copy.</returns>
        public AuthenticationProperties Clone()
            => new AuthenticationProperties(
                new Dictionary<string, string?>(Items, StringComparer.Ordinal),
                new Dictionary<string, object?>(Parameters, StringComparer.Ordinal));

        /// <summary>
        /// State values about the authentication session.
        /// </summary>
        public IDictionary<string, string?> Items { get; }

        /// <summary>
        /// Collection of parameters that are passed to the authentication handler. These are not intended for
        /// serialization or persistence, only for flowing data between call sites.
        /// </summary>
        [JsonIgnore]
        public IDictionary<string, object?> Parameters { get; }

        /// <summary>
        /// Gets or sets whether the authentication session is persisted across multiple requests.
        /// </summary>
        [JsonIgnore]
        public bool IsPersistent
        {
            get => GetString(IsPersistentKey) != null;
            set => SetString(IsPersistentKey, value ? string.Empty : null);
        }

        /// <summary>
        /// Gets or sets the full path or absolute URI to be used as an http redirect response value.
        /// </summary>
        [JsonIgnore]
        public string? RedirectUri
        {
            get => GetString(RedirectUriKey);
            set => SetString(RedirectUriKey, value);
        }

        /// <summary>
        /// Gets or sets the time at which the authentication ticket was issued.
        /// </summary>
        [JsonIgnore]
        public DateTimeOffset? IssuedUtc
        {
            get => GetDateTimeOffset(IssuedUtcKey);
            set => SetDateTimeOffset(IssuedUtcKey, value);
        }

        /// <summary>
        /// Gets or sets the time at which the authentication ticket expires.
        /// </summary>
        [JsonIgnore]
        public DateTimeOffset? ExpiresUtc
        {
            get => GetDateTimeOffset(ExpiresUtcKey);
            set => SetDateTimeOffset(ExpiresUtcKey, value);
        }

        /// <summary>
        /// Gets or sets if refreshing the authentication session should be allowed.
        /// </summary>
        [JsonIgnore]
        public bool? AllowRefresh
        {
            get => GetBool(RefreshKey);
            set => SetBool(RefreshKey, value);
        }

        /// <summary>
        /// Get a string value from the <see cref="Items"/> collection.
        /// </summary>
        /// <param name="key">Property key.</param>
        /// <returns>Retrieved value or <c>null</c> if the property is not set.</returns>
        public string? GetString(string key)
        {
            return Items.TryGetValue(key, out var value) ? value : null;
        }

        /// <summary>
        /// Set or remove a string value from the <see cref="Items"/> collection.
        /// </summary>
        /// <param name="key">Property key.</param>
        /// <param name="value">Value to set or <see langword="null" /> to remove the property.</param>
        public void SetString(string key, string? value)
        {
            if (value != null)
            {
                Items[key] = value;
            }
            else
            {
                Items.Remove(key);
            }
        }

        /// <summary>
        /// Get a parameter from the <see cref="Parameters"/> collection.
        /// </summary>
        /// <typeparam name="T">Parameter type.</typeparam>
        /// <param name="key">Parameter key.</param>
        /// <returns>Retrieved value or the default value if the property is not set.</returns>
        public T? GetParameter<T>(string key)
            => Parameters.TryGetValue(key, out var obj) && obj is T value ? value : default;

        /// <summary>
        /// Set a parameter value in the <see cref="Parameters"/> collection.
        /// </summary>
        /// <typeparam name="T">Parameter type.</typeparam>
        /// <param name="key">Parameter key.</param>
        /// <param name="value">Value to set.</param>
        public void SetParameter<T>(string key, T value)
            => Parameters[key] = value;

        /// <summary>
        /// Get a nullable <see cref="bool"/> from the <see cref="Items"/> collection.
        /// </summary>
        /// <param name="key">Property key.</param>
        /// <returns>Retrieved value or <see langword="null" /> if the property is not set.</returns>
        protected bool? GetBool(string key)
        {
            if (Items.TryGetValue(key, out var value) && bool.TryParse(value, out var boolValue))
            {
                return boolValue;
            }
            return null;
        }

        /// <summary>
        /// Set or remove a <see cref="bool"/> value in the <see cref="Items"/> collection.
        /// </summary>
        /// <param name="key">Property key.</param>
        /// <param name="value">Value to set or <see langword="null" /> to remove the property.</param>
        protected void SetBool(string key, bool? value)
        {
            if (value.HasValue)
            {
                Items[key] = value.GetValueOrDefault().ToString();
            }
            else
            {
                Items.Remove(key);
            }
        }

        /// <summary>
        /// Get a nullable <see cref="DateTimeOffset"/> value from the <see cref="Items"/> collection.
        /// </summary>
        /// <param name="key">Property key.</param>
        /// <returns>Retrieved value or <see langword="null" /> if the property is not set.</returns>
        protected DateTimeOffset? GetDateTimeOffset(string key)
        {
            if (Items.TryGetValue(key, out var value)
                && DateTimeOffset.TryParseExact(value, UtcDateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTimeOffset))
            {
                return dateTimeOffset;
            }
            return null;
        }

        /// <summary>
        /// Sets or removes a <see cref="DateTimeOffset" /> value in the <see cref="Items"/> collection.
        /// </summary>
        /// <param name="key">Property key.</param>
        /// <param name="value">Value to set or <see langword="null" /> to remove the property.</param>
        protected void SetDateTimeOffset(string key, DateTimeOffset? value)
        {
            if (value.HasValue)
            {
                Items[key] = value.GetValueOrDefault().ToString(UtcDateTimeFormat, CultureInfo.InvariantCulture);
            }
            else
            {
                Items.Remove(key);
            }
        }
    }
}

 

posted @ 2021-09-11 17:47  重构者  阅读(164)  评论(0编辑  收藏  举报