6

NB I got warning that there are many similar questions available. However, those are mostly regarding other concepts such as difference between user managers and user stores (and also, difference between a bunch of unrelated things, so I'm guessing Stacky weights in difference equally). However, googling difference AspNetUserManager UserManager produces a lot of guides on how to set up security without discussing the actual difference.

So, I went to the good old MSDN and looked up those two classes. Apparently, AspNetUsermanager is described like this.

Provides the APIs for managing user in a persistence store.

And that, while UserManager is described like this.

Provides the APIs for managing user in a persistence store.

One would expect certain overlap in functionality between those two, given that both are meant for managing users. However, I feel that it might behoove the reader to be presented with a bit more variation in the, certainly so, true formulation.

My question is - how do they relate (i.e. under what circumstances is the former preferred over the latter)?

Julian
  • 33,915
  • 22
  • 119
  • 174
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • `UserManager` is Derived from `AspNetUserManager` : Inheritance `Object --> UserManager --> AspNetUserManager` – Alireza Ahmadi Aug 02 '21 at 10:36
  • @AlirezaAhmadi I get that. You might want to post it as an answer to be accepted, especially if you throw in some info on when to use which and/or why we have an inheriting version at all, instead of using the one that already existed (alternatively, why they kept the inherited class at all). I'm thinking, if the inheriting one is **always** to be used, why not simply add the features of it to the old one and keep it simple? – Konrad Viltersten Aug 02 '21 at 13:40

1 Answers1

9

If I check the code, the only difference is that AspNetUserManager<TUser> gets the (default) cancelationtoken from the httpcontext (on request aborted). I guess that gives a better experience when canceling the request. All other methods and properties are inherited from the UserManager<TUser>

/// <summary>
    /// Provides the APIs for managing user in a persistence store.
    /// </summary>
    /// <typeparam name="TUser">The type encapsulating a user.</typeparam>
    public class AspNetUserManager<TUser> : UserManager<TUser>, IDisposable where TUser : class
    {
        private readonly CancellationToken _cancel;

        /// <summary>
        /// Constructs a new instance of <see cref="AspNetUserManager{TUser}"/>.
        /// </summary>
        /// <param name="store">The persistence store the manager will operate over.</param>
        /// <param name="optionsAccessor">The accessor used to access the <see cref="IdentityOptions"/>.</param>
        /// <param name="passwordHasher">The password hashing implementation to use when saving passwords.</param>
        /// <param name="userValidators">A collection of <see cref="IUserValidator{TUser}"/> to validate users against.</param>
        /// <param name="passwordValidators">A collection of <see cref="IPasswordValidator{TUser}"/> to validate passwords against.</param>
        /// <param name="keyNormalizer">The <see cref="ILookupNormalizer"/> to use when generating index keys for users.</param>
        /// <param name="errors">The <see cref="IdentityErrorDescriber"/> used to provider error messages.</param>
        /// <param name="services">The <see cref="IServiceProvider"/> used to resolve services.</param>
        /// <param name="logger">The logger used to log messages, warnings and errors.</param>
        public AspNetUserManager(IUserStore<TUser> store,
            IOptions<IdentityOptions> optionsAccessor,
            IPasswordHasher<TUser> passwordHasher,
            IEnumerable<IUserValidator<TUser>> userValidators,
            IEnumerable<IPasswordValidator<TUser>> passwordValidators,
            ILookupNormalizer keyNormalizer,
            IdentityErrorDescriber errors,
            IServiceProvider services,
            ILogger<UserManager<TUser>> logger)
            : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
        {
            _cancel = services?.GetService<IHttpContextAccessor>()?.HttpContext?.RequestAborted ?? CancellationToken.None;
        }

        /// <summary>
        /// The cancellation token associated with the current HttpContext.RequestAborted or CancellationToken.None if unavailable.
        /// </summary>
        protected override CancellationToken CancellationToken => _cancel;
   }

From https://github.com/dotnet/aspnetcore/blob/main/src/Identity/Core/src/AspNetUserManager.c

Very related, there is a suggestion to get rid of this class:

Consider adding optional cancellationToken to manager APIs

If we do this in 3.0, we could probably also get rid of the automatic HttpRequest.Aborted hookup, which would let us get rid of the derived AspNetUserManager entirely.

See https://github.com/dotnet/aspnetcore/issues/5763

Julian
  • 33,915
  • 22
  • 119
  • 174