7

I followed this article (https://learn.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.

imsome1
  • 1,182
  • 4
  • 22
  • 37
Bluesight
  • 754
  • 1
  • 11
  • 29
  • 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. – Robert Oct 18 '17 at 08:45
  • 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 Oct 18 '17 at 08:51
  • 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. – Robert Oct 18 '17 at 08:55
  • 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 Oct 18 '17 at 09:03
  • 1
    @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 Oct 18 '17 at 09:08
  • I heard this before but that is simply not true. When you pass the name in contructor that is the default that is used for all schemes. Use this CookieAuthenticationDefaults.AuthenticationScheme instead of "MyCookieAuthenticationScheme". This is in Microsoft.AspNetCore.Authentication.Cookies. Be sure to put it in the AccountController, in the method that authenticates. – Robert Oct 18 '17 at 09:11
  • Yes, that's what I thought as well. Actually it should be used for all schemes, but it isn't. Now it's really working! It's very strange. So I tried your solution, replaced my "MyCookieAuthenticationScheme" with CookieAuthenticationDefaults.AuthenticationScheme in all Files, but it doesn't work. But it works when setting these options separately.. seems like this guy had the same problem: https://stackoverflow.com/questions/46057109/why-doesnt-my-cookie-authentication-work-in-asp-net-core – Bluesight Oct 18 '17 at 09:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156987/discussion-between-rob-and-bluesight). – Robert Oct 18 '17 at 09:21

4 Answers4

3

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.

Octavian Mărculescu
  • 4,312
  • 1
  • 16
  • 29
2

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://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity

Orhun
  • 1,162
  • 14
  • 22
  • I'm using a MySQL Database, so I would need to overwrite PasswordSignInAsync method. I thought the cookie Authentication would be easier. But it seems like I will got this way. – Bluesight Oct 18 '17 at 08:47
  • this was also approp approach for me, HttpContext approach did not work, this did – sobelito Aug 13 '20 at 13:55
0

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!

Ben Walters
  • 688
  • 6
  • 9
  • 1
    Downvoted because `AuthenticationHttpContextExtensions.SignInAsync` is just an extension method ON `HttpContext.SignInAsync()`, and thus they're the same thing. – Stuart.Sklinar Jun 22 '18 at 08:58
0

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.

Rajon Tanducar
  • 308
  • 4
  • 8