Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net identity userName is unique?

I was reading about user Identity in Microsoft and trying to apply them in my MVC5 app.

Up to my knowledge the Id is the key, while the userName is not key and the definition says that it can be null, so I was asking myself... why in the MVC5 project template, when you enter an already existing userName you will receive an Error message ??

I tried to reach to the userName validation but I couldn't.

Here is the database definition:

CREATE TABLE [dbo].[AspNetUsers] (
    [Id]            NVARCHAR (128) NOT NULL,
    [UserName]      NVARCHAR (MAX) NULL,

and here is the IdentityUser definition, notice (no validation):

namespace Microsoft.AspNet.Identity.EntityFramework
{
    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);

        public virtual ICollection<IdentityUserClaim> Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection<IdentityUserLogin> Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection<IdentityUserRole> Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
}

and on registration, the UserManager.CreateAsync method is called, here is the definition:

     public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser() { UserName = model.UserName };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    AddErrors(result);
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

and this is the last thing I reach regarding CreateAsync:

public virtual Task<IdentityResult> CreateAsync(TUser user, string password);

I don't see validation anywhere in the code, however it won't allow you to enter an existing userName.

I think understanding how does this works will improve my experience with the Identity concept of asp.net and will improve my code.

Any guidance is highly appreciated

like image 967
stackunderflow Avatar asked Apr 12 '14 08:04

stackunderflow


People also ask

What is identity user in asp net?

ASP.NET Core Identity provides a framework for managing and storing user accounts in ASP.NET Core apps. Identity is added to your project when Individual User Accounts is selected as the authentication mechanism. By default, Identity makes use of an Entity Framework (EF) Core data model.

What is ASP.NET Core identity used for?

ASP.NET Core Identity: Is an API that supports user interface (UI) login functionality. Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more.

What is user identity in C#?

It just holds the username of the user that is currently logged in. After login successful authentication, the username is automatically stored by login authentication system to "HttpContext.Current.User.Identity.Name" property.

What is ASP NET identity claims?

Claims can be created from any user or identity data which can be issued using a trusted identity provider or ASP.NET Core identity. A claim is a name value pair that represents what the subject is, not what the subject can do.


1 Answers

This happens in IdentityDbContext<TUser>, which your ApplicationDbContext probably inherits from. It overrides DbContext's ValidateEntity method to do the check. See this decompiled code:

    protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        if ((entityEntry != null) && (entityEntry.State == EntityState.Added))
        {
            TUser user = entityEntry.Entity as TUser;
            if ((user != null) && this.Users.Any<TUser>(u => string.Equals(u.UserName, user.UserName)))
            {
                return new DbEntityValidationResult(entityEntry, new List<DbValidationError>()) { ValidationErrors = { new DbValidationError("User", string.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, new object[] { user.UserName })) } };
            }
            IdentityRole role = entityEntry.Entity as IdentityRole;
            if ((role != null) && this.Roles.Any<IdentityRole>(r => string.Equals(r.Name, role.Name)))
            {
                return new DbEntityValidationResult(entityEntry, new List<DbValidationError>()) { ValidationErrors = { new DbValidationError("Role", string.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, new object[] { role.Name })) } };
            }
        }
        return base.ValidateEntity(entityEntry, items);
    }

If you don't want this behavior you can inherit from DbContext directly.

like image 83
Casey Avatar answered Oct 27 '22 07:10

Casey