AspNetCore 2.0 Claims always empty

Danny Ellis Jr. picture Danny Ellis Jr. · Aug 28, 2017 · Viewed 9k times · Source

I am working on converting a DotNet 4.5 MVC/WebAPI application to AspNetCore 2.0, and I'm having some trouble getting my Cookie authentication working again. When I set the cookie and try to access a secure method, I can't get there. When I go into an anonymous method and inspect the user object, it is empty - no authentication type, no claims, etc.

I have followed this article as best I can: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x. I am not using Identity.

My code in startup.cs ConfigureServices is as follows:

  services.AddAuthentication("ACE_AUTH")                    
                    .AddCookie("ACE_AUTH",  options =>
                    {
                        options.AccessDeniedPath = "/Home/Index/";
                        options.LoginPath = "/Home/Index/";
                    });

My code in the Configure method:

app.UseAuthentication();

The Principal is fully populated when this is called. Where I am setting my cookie:

 await HttpContext.SignInAsync("ACE_AUTH", samlData.Principal);

Nothing I have tried has caused my claims to show up when attempting to Authenticate the user.

Answer

sec0ndHand picture sec0ndHand · Sep 13, 2017

Here is what is working for me: Most of what I learned comes from this microsoft doc but as you said the documentation doesn't seem to take you all the way there.

in startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        ...

        services.AddAuthentication("ACE_AUTH")
        .AddCookie("ACE_AUTH", options => {
            options.AccessDeniedPath = "/api/Auth/Forbidden";
            options.LoginPath = "/";
            options.Cookie.Expiration = new TimeSpan(7,0,0,0);
        });
    }


public void Configure(IApplicationBuilder app, 
                      IHostingEnvironment env, 
                      ILoggerFactory loggerFactory)
    {
        ...

        app.UseAuthentication();
    }

And then in your controller that handles authentication:

    [HttpPost()]
    [Route("api/[Controller]/[Action]/")]
    public async Task<JsonResult> Login([FromBody]Dictionary<string, string> loginData)
    {
        try
        {
            var loggedIn = true;
            if (loggedIn)
            {
                var claims = new List<Claim> {
                    new Claim(ClaimTypes.Name, "John Doe")
                };

                var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                identity.AddClaims(claims);
                ClaimsPrincipal principal = new ClaimsPrincipal(identity);

                await HttpContext.SignInAsync(
                    "ACE_AUTH",
                    principal,
                    new AuthenticationProperties
                    {
                        IsPersistent = true,
                        ExpiresUtc = DateTime.UtcNow.AddDays(7)
                    });
            }
            return new JsonResult(logRtn);
        }
        catch (Exception ex)
        {
            return new JsonResult(ex.Message);
        }
    }

If you can authenticate and assign loggedIn the result of your authentication request, you should be able to store claims in the cookie. You can then recall that claim in a controller that might be doing authorization/recalling values using the following:

    [HttpGet("[Action]", Name = "GetSomething")]
    [Route("[Action]")]
    public JsonResult something()
    {
        try
        {
            var loggedInUser = HttpContext.User;
            var claym = loggedInUser.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name);
            if (claym != null)
            {
                return new JsonResult(claym.Value);
                // returns "John Doe"
            }
            else
            {
                return new JsonResult("");
            }
        }
        catch (Exception ex)
        {
            return new JsonResult(ex.Message);
        }
    }