6
votes

I followed this article (https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x) of Microsoft to migrate my Authentication Procedure in my .NET Core 2.0 MVC Application.

Startup.cs (ConfigureServices)

services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

services.AddAuthentication("MyCookieAuthenticationScheme")
        .AddCookie("MyCookieAuthenticationScheme", options => {
            options.AccessDeniedPath = "/Account/Forbidden/";
            options.LoginPath = "/Account/Login/";
        });

Startup.cs (Configure)

app.UseAuthentication();

AccountController.cs

List<Claim> claims = new List<Claim> {
                        new Claim(ClaimTypes.Name, "testUser"),
                        new Claim(ClaimTypes.Email, model.Email),
                        //new Claim("ID", user.ID.ToString(), ClaimValueTypes.Integer),
                        new Claim(ClaimTypes.Role, "Admin")
                    };

ClaimsIdentity identity = new ClaimsIdentity(claims, "MyCookieAuthenticationScheme");

ClaimsPrincipal principal = new ClaimsPrincipal(identity);

await HttpContext.SignInAsync("MyCookieAuthenticationScheme", principal, new AuthenticationProperties
{
    IsPersistent = false
});

Unfortunately my .NET Cookie is never set. That means User.Identity.IsAuthenticated is always false. I tried many cookie options like changing Cookie.SameSite or Cookie.SecurePolicy to all possible values.

I work with Visual Studio 2017, localhost over https, Chrome 61.

4
Have you actualy checked if no cookie is set or are you just presuming since you cannot authenticate? Check the browser developer console for cookies because I am pretty sure this code would set the cookie. - Rob
Uuh, you're right. I just checked the console and it's generated. Do you know why the Identity won't be set though? - Bluesight
Can you remove the AddIdentity(...) and during the authentication just supply it with some fixed values to see if the problem is in identity because this code is pretty straight forward and it works. - Rob
If I remove it it will fail as soon as it calls any view with UserManager in it: InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.UserManager`1[PTCConnector.Models.ApplicationUser]' has been registered. - Bluesight
@Rob I got the solution working now: the trick is that all your components need to refer to the same identity id. So I needed to set DefaultChallengeScheme, DefaultAuthenticateScheme and DefaultScheme to MyCookieAuthenticationScheme in the options of AddAuthentication.. - Bluesight

4 Answers

3
votes

Assuming that you are serving your application on localhost, it seems that the Chrome browser does not set the cookies for IPs or intranet hostnames like localhost. You can serve your application from IIS and use a binding with a valid host name.

2
votes

I think you should provide login process using by Identity's UserManager class instead of HttpContext.SignInAsync. Inject IUserManager to your controller constructor, and use it to login.

AccountController: Controller
{
    private readonly SignInManager<ApplicationUser> _signInManager;

    public AccountController(SignInManager<ApplicationUser> singInManager)
    {
        _signInManager = signInManager;
    }

    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
        ...
    }

}

You can modify Identity's cookie settings in your Startup.cs. Take a glance:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

0
votes

When upgrading our site's authentication system for .NET Core 2.0, I had to update our controller method to use the AuthenticationHttpContextExtensions.SignInAsync() method instead of the old HttpContext.SignInAsync().

Example:

public async Task ClaimsLogin() {

    // Claims identity creation here...

    ClaimsPrincipal principal = new ClaimsPrincipal(identity);

    await Task.FromResult(
        AuthenticationHttpContextExtensions.SignInAsync(
            this.httpContextAccessor.HttpContext,
            "NameOfYourCookieHere",
            userPrincipal,
            new AuthenticationProperties()
            {
                ExpiresUtc = DateTime.UtcNow.AddMinutes(2880),
                IsPersistent = false,
                AllowRefresh = false
            }));
}

Hopefully this helps someone!

0
votes

I was getting the same issue, after trying lot of googling and stackoverflow answers for hours I couldn't log in despite getting success from the SignInManager. So what I did solve the problem is added .AspNetCore.Identity.Application in cookie Name manually, and added a random token in the value field then I was able to log in sucessfully. Again after logging out the identity token was gone from the cookie but after login in again it came in the cookie this time.

I hope this process helps some one who has gone through like me.