shreesharao / aspnetcore-ConsoleToWeb

Convert Console project to web project for understanding the working of asp.net core mvc
0 stars 0 forks source link

SignInManager.IsSignedIn(User) == false, yet User.Identity.IsAuthenticated == true when going to dashboard view #13

Closed shreesharao closed 6 years ago

shreesharao commented 6 years ago

In the Login action method i had

[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Login(LoginViewModel loginViewModel)
        {

            if (ModelState.IsValid)
            {
                var result = await _signInManager.PasswordSignInAsync(loginViewModel.Email, loginViewModel.Password, loginViewModel.Rememberme, lockoutOnFailure: true);

                if (result.Succeeded)
                {

                    //set cookie
                    var claims = new List<Claim>()
                    {
                        new Claim(ClaimTypes.Name,loginViewModel.Email),
                        new Claim(ClaimTypes.Role,$"Administrator")
                    };

                    var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

                    var authProperties = new AuthenticationProperties();

                    //Make the cookie persisitent if the user wants to
                    if(loginViewModel.Rememberme)
                    {
                        authProperties.IsPersistent = true;
                    }

                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);

                    return RedirectToAction("Dashboard", "Library");
                }
                else
                {
                    _logger.LogError($"{result}");
                }
            }

            return View(loginViewModel);
        }

and in Library controller i had code which was working fine

[HttpGet]
        [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme, Roles = "Administrator")]
        public IActionResult Dashboard()
        {
            return View();
        }

and in Dashboard view i had below code where SignInManager.IsSignedIn(User) was failing

@inject SignInManager<ApplicationUser<Guid>> SignInManager
@inject UserManager<ApplicationUser<Guid>> UserManager

@if (SignInManager.IsSignedIn(User))
{
    <h3>upon successfull authentication we will reach here</h3>
    <ul>
        @foreach (Claim claim in User.Claims)
        {
            <li>@claim.Subject.Name</li>
            <li>@claim.Value</li>
        }
    </ul>

}
else
{
    <ul>
        <li>
            <a asp-action="Login" asp-controller="Profile">Log In</a>
        </li>
        <li>
            <a asp-action="Register" asp-controller="Profile">Register</a>
        </li>
    </ul>
}
shreesharao commented 6 years ago

Refer https://github.com/aspnet/Security/issues/1538.

comments relevent

SignInManager is part of the Identity framework. The configuration you're showing is not using the Identity framework, it's only using the Authentication components.

SignInManager is looking specifically for the identity application cookie (.AspNetCore.Identity.Application), you only want to use that method if you are using SignInManager to sign in typically.

shreesharao commented 6 years ago

When i changed the Login action method code to use IdentityConstants.ApplicationScheme for cookies, SignInManager.IsSignedIn(User) returned true

[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Login(LoginViewModel loginViewModel)
        {

            if (ModelState.IsValid)
            {
                var result = await _signInManager.PasswordSignInAsync(loginViewModel.Email, loginViewModel.Password, loginViewModel.Rememberme, lockoutOnFailure: true);

                if (result.Succeeded)
                {

                    //set cookie
                    var claims = new List<Claim>()
                    {
                        new Claim(ClaimTypes.Name,loginViewModel.Email),
                        new Claim(ClaimTypes.Role,$"Administrator")
                    };

                    var claimsIdentity = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);

                    var authProperties = new AuthenticationProperties();

                    //Make the cookie persisitent if the user wants to
                    if(loginViewModel.Rememberme)
                    {
                        authProperties.IsPersistent = true;
                    }

                    await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);

                    return RedirectToAction("Dashboard", "Library");
                }
                else
                {
                    _logger.LogError($"{result}");
                }
            }

            return View(loginViewModel);
        }

LibraryController.cs

public class LibraryController : Controller
    {
        [HttpGet]
        [Authorize(AuthenticationSchemes =  "Identity.Application", Roles = "Administrator")]
        public IActionResult Dashboard()
        {
            return View();
        }
    }
shreesharao commented 6 years ago

Refer to this issue - https://github.com/shreesharao/aspnetcore-ConsoleToWeb/issues/14 , for Authentication with Cookies without using AspNetCore Identity.