locked
EF Core Identity exception RRS feed

  • Question

  • User1034688386 posted

    I am trying to get a custom implementation of the Identity interface working in ASP.NET MVC and SQL Server.

    1) created a database project with table definitions for all of the Identity tables: ApplicationUser, ApplicationRole, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim, ApplicationUserToken

    2) published database project to instance of SQL Server

    3) used Scaffold-DbContext to create Entity Framework Core context and entities from schema published to SQL

    4) modified context to inherit IdentityDbContext

        : IdentityDbContext<
        ApplicationUser,
        ApplicationRole,
        int,
        ApplicationUserClaim,
        ApplicationUserRole,
        ApplicationUserLogin,
        ApplicationRoleClaim,
        ApplicationUserToken>
    

    5) created a user

        Entities.ApplicationUser user = new Entities.ApplicationUser()
        {
        UserName = username,
        Email = "test@test.com",
        PhoneNumber = "999-999-9999",
        };
    
        await _userManager.UpdateSecurityStampAsync(user);
        await _userManager.CreateAsync(user, password);
    

    6) created a role

        Entities.ApplicationRole role = new Entities.ApplicationRole();
        role.Name = rolename;
        IdentityResult identityResult = await _roleManager.CreateAsync(role);
    

    7) added user to role

        Entities.ApplicationUser user = await _userManager.FindByNameAsync(username);
        await _userManager.AddToRolesAsync(user, roleNames);
    

    8) attempted to use password sign in

        Entities.ApplicationUser user = await _userManager.FindByNameAsync(username);
        bool canSignIn = await _signInManager.CanSignInAsync(user);
        var x = await _signInManager.CheckPasswordSignInAsync(user, password, false);
        Microsoft.AspNetCore.Identity.SignInResult signInResult = 
        await _signInManager.PasswordSignInAsync(user, password, false, false);
    

    Everything above works except password sign in. CanSignInAsync returns true and CheckPasswordSignInAsync returns Succeeded true, but PasswordSignInAsync throws an exception that when caught says Message = "Value cannot be null. (Parameter 'value')" and Source = "System.Security.Claims".  What am I doing wrong?

    Sunday, January 12, 2020 3:57 AM

Answers

  • User1034688386 posted

    The issue was that my ApplicationUser and ApplicationRole tables were beginning with Id 0, and SignInManager would not work unless the tables begin at Id 1.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 23, 2020 5:21 AM

All replies

  • User665608656 posted

    Hi Aaron,

    Based on your description, can you provide DbContext content that inherits from IdentityDbContext?

    And did you rewrite the contents of _signInManager?

    If so, please provide us with the details.

    Best Regards,

    YongQing.

    Monday, January 13, 2020 9:43 AM
  • User1034688386 posted

    YongQing,

    Thank you for your reply.  I did not rewrite SignInManager, and the DbContext is below.  Also, I noticed that PasswordSignInAsync calls SignInOrTwoFactorAsync which calls context.SignInAsync, and when I call HttpContext.SignInAsync I get a different exception {"SignInAsync when principal.Identity.IsAuthenticated is false is not allowed when AuthenticationOptions.RequireAuthenticatedSignIn is true."}

    using System;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    
    namespace Registrations.Entities
    {
        public partial class RegistrationsContext : IdentityDbContext<
            ApplicationUser,
            ApplicationRole,
            int,
            ApplicationUserClaim,
            ApplicationUserRole,
            ApplicationUserLogin,
            ApplicationRoleClaim,
            ApplicationUserToken>
        {
            public RegistrationsContext()
            {
            }
    
            public RegistrationsContext(DbContextOptions<RegistrationsContext> options)
                : base(options)
            {
            }
    
            public virtual DbSet<ApplicationRole> ApplicationRole { get; set; }
            public virtual DbSet<ApplicationRoleClaim> ApplicationRoleClaim { get; set; }
            public virtual DbSet<ApplicationUser> ApplicationUser { get; set; }
            public virtual DbSet<ApplicationUserClaim> ApplicationUserClaim { get; set; }
            public virtual DbSet<ApplicationUserLogin> ApplicationUserLogin { get; set; }
            public virtual DbSet<ApplicationUserRole> ApplicationUserRole { get; set; }
            public virtual DbSet<ApplicationUserToken> ApplicationUserToken { get; set; }
            public virtual DbSet<Registration> Registration { get; set; }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                if (!optionsBuilder.IsConfigured)
                {
                    optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("DevConnection"));
                }
            }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<ApplicationRole>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.ConcurrencyStamp).IsRequired();
    
                    entity.Property(e => e.Name).IsRequired();
    
                    entity.Property(e => e.NormalizedName).IsRequired();
                });
    
                modelBuilder.Entity<ApplicationRoleClaim>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.ClaimType).IsRequired();
    
                    entity.Property(e => e.ClaimValue).IsRequired();
    
                    entity.HasOne(d => d.Role)
                        .WithMany(p => p.ApplicationRoleClaim)
                        .HasForeignKey(d => d.RoleId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("FK_ApplicationRoleClaim_RoleId");
                });
    
                modelBuilder.Entity<ApplicationUser>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.ConcurrencyStamp).IsRequired();
    
                    entity.Property(e => e.Email).IsRequired();
    
                    entity.Property(e => e.NormalizedEmail).IsRequired();
    
                    entity.Property(e => e.NormalizedUserName).IsRequired();
    
                    entity.Property(e => e.PasswordHash).IsRequired();
    
                    entity.Property(e => e.PhoneNumber).IsRequired();
    
                    entity.Property(e => e.SecurityStamp).IsRequired();
    
                    entity.Property(e => e.UserName).IsRequired();
                });
    
                modelBuilder.Entity<ApplicationUserClaim>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.ClaimType).IsRequired();
    
                    entity.Property(e => e.ClaimValue).IsRequired();
    
                    entity.HasOne(d => d.User)
                        .WithMany(p => p.ApplicationUserClaim)
                        .HasForeignKey(d => d.UserId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("FK_ApplicationUserClaim_ApplicationUser");
                });
    
                modelBuilder.Entity<ApplicationUserLogin>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.LoginProvider).IsRequired();
    
                    entity.Property(e => e.ProviderDisplayName).IsRequired();
    
                    entity.Property(e => e.ProviderKey).IsRequired();
    
                    entity.HasOne(d => d.User)
                        .WithMany(p => p.ApplicationUserLogin)
                        .HasForeignKey(d => d.UserId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("FK_ApplicationUserLogin_UserId");
                });
    
                modelBuilder.Entity<ApplicationUserRole>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.HasOne(d => d.Role)
                        .WithMany(p => p.ApplicationUserRole)
                        .HasForeignKey(d => d.RoleId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("FK_ApplicationUserRole_ApplicationRole");
    
                    entity.HasOne(d => d.User)
                        .WithMany(p => p.ApplicationUserRole)
                        .HasForeignKey(d => d.UserId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("FK_ApplicationUserRole_ApplicationUser");
    
                    entity.HasKey(u => new { u.RoleId, u.UserId });
                });
    
                modelBuilder.Entity<ApplicationUserToken>(entity =>
                {
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.LoginProvider).IsRequired();
    
                    entity.Property(e => e.Name).IsRequired();
    
                    entity.Property(e => e.Value).IsRequired();
    
                    entity.HasOne(d => d.User)
                        .WithMany(p => p.ApplicationUserToken)
                        .HasForeignKey(d => d.UserId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("FK_ApplicationUserToken_UserId");
                });
    
                modelBuilder.Entity<Registration>(entity =>
                {
                    entity.HasIndex(e => e.Url)
                        .HasName("UQ_Registration_Url")
                        .IsUnique();
    
                    entity.Property(e => e.Id).ValueGeneratedNever();
    
                    entity.Property(e => e.Login).IsRequired();
    
                    entity.Property(e => e.Password).IsRequired();
    
                    entity.Property(e => e.Url)
                        .IsRequired()
                        .HasMaxLength(50);
                });
    
                OnModelCreatingPartial(modelBuilder);
            }
    
            partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
        }
    }
    

    Monday, January 13, 2020 4:17 PM
  • User1034688386 posted

    The issue was that my ApplicationUser and ApplicationRole tables were beginning with Id 0, and SignInManager would not work unless the tables begin at Id 1.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 23, 2020 5:21 AM