AspNetCore 2.0 Claims always empty

12.9k views Asked by At

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://learn.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.

2

There are 2 answers

0
sec0ndHand On

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);
        }
    }
0
Dirk Boer On

For people not reading comments (almost read over it myself):

Joey: "What solved the issue for me was moving app.UseAuthentication above app.UseMvc. It does say that in the docs but it is well hidden."

... This works... Why it doesn't throw an Exception when you do it afterwards is behind me.