Search code examples
c#asp.net-coreasp.net-identity

AspNet.Core Identity - Cannot sign in user


Here is my situation:

I'm working on an app that will require user login. For the UI portion, I created an MVC app with local user accounts. I will have to extend the User with properties, which was always pretty cut and dry. I extended the User and moved it into the domain-layer project. I also moved the context out, which again, pretty cut and dry and I've done this several times before.

However, Identity Core seems to be.... different. I'd use the default UI if the views were exposed, but they appear to be deep in a Nuget package somewhere (? that's another question I have).

My Context inherits the IdentityDbContext class:

public class MyContext : IdentityDbContext<User, IdentityRole, string>, IMyContext

I register the identity stuff in Startup.cs:

        services
            .AddIdentity<User, IdentityRole>()
            .AddEntityFrameworkStores<MyContext>()
            .AddDefaultTokenProviders();


        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        services.AddAuthorization();

I created an authorizationManager that is meant to deal with anything in the Authorization domain. I inject the userManager and signInManager:

public AuthorizationManager(UserManager<User> userManager,
    SignInManager<User> signInManager,
    IMapper mapper)
    {
        _signInManager = signInManager;
        _userManager = userManager;
        _mapper = mapper;
    }

And then Login the user like so:

    public async Task<UserDto> LoginUser(UserLoginInput input)
    {
        var user = input.UserNameOrEmail.Contains("@") ? 
            await _userManager.FindByEmailAsync(input.UserNameOrEmail) :
            await _userManager.FindByNameAsync(input.UserNameOrEmail);

        var signInResult = await _signInManager.CheckPasswordSignInAsync(user, input.Password, false);

        return signInResult.Succeeded ?
            _mapper.Map<UserDto>(user) :
            null;
    }

The login result does give me Succeeded, yet after this, I'm never able to access that user or the roles they fill. I've checked the the User and Role exists in the database, and that the UserRole xref exists. But with all this, I'm still returning null:

var user = await _userManager.GetUserAsync(HttpContext.User);

I suspect I'm not quite hooked into AspNetCores Identity, but after a couple days of going through this, I can't quite pinpoint where or why. Any help or insight would be greatly appreciated.

Update

Not sure if this is related, but I am also configuring the Application Cookie as part of the startup:

        services.ConfigureApplicationCookie(options =>
        {
            options.AccessDeniedPath = "/Authorization/AccessDenied";
            options.Cookie.Name = "MyApplication_Auth";
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromDays(7);
            options.LoginPath = "/Authorization/Login";
            options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
            options.SlidingExpiration = true;
        });

Solution

  • First, I believe your HttpContext.User will always be null unless you use the [Authorize] attribute.

    Second, I think your cookie customization looks fine, but I don't see where you're calling UseAuthentication():

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) {
        ⋮
        app.UseAuthentication();
        ⋮
    }
    

    Reference: Configure Identity services

    Identity is enabled by calling UseAuthentication. UseAuthentication adds authentication middleware to the request pipeline.

    Third, you can find info on customizing all the Identity views here: Create full identity UI source