2

I am creating CookieAutentecation signin for my Web API.

I have read and followed the official article here and I have done everything correctly as far as I am concerned.

But when I put breakpoints in my controllers and inspect HttpContext.User, everything is always null, no Username, no claims, nothing.

What else do I need to make this work? Are additional steps needed for Web API vs MVC app?

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors();

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, act => {
                act.LoginPath = "/api/login";
                act.AccessDeniedPath = "/api/login";
                act.SlidingExpiration = true;
            });

    services.AddControllers();

    services.AddServices(); // <- Own app domain services 
    services.AddDataAccess(); // <- Own app domain data access
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCors(
            options => options.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
        );

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
}

api/login

var user = new SecurityUser()
        {
            UserID = 123,
            CompleteName = "Test user",
            FirstName = "Test",
            Email = "[email protected]"
        };
var identity = user.ToClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, 123);
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties()
        {
            AllowRefresh = true,
           ExpiresUtc = DateTime.UtcNow.AddDays(7),
           IsPersistent = true,
        });

ToClaimsIdentity extension method:

public static ClaimsIdentity ToClaimsIdentity(this SecurityUser user, string authenticantionType, int auditUserID)
{
        var claims = new List<Claim>()
        {
            new Claim(ClaimTypes.NameIdentifier, user.UserID.ToString()),
            new Claim(ClaimTypes.Email, user.Email),
            new Claim(ClaimTypes.Name, user.FirstName),
            new Claim(SecurityUserClaimTypes.AuditUserID, auditUserID.ToString())
        };

        var identity = new ClaimsIdentity(claims, authenticantionType);
        return identity;
}

Any help would be greatly appreciated.

Edit - This is what I am taking about 👇 enter image description here

6
  • Have you added [Authorize] to your controllers? Commented Apr 1, 2020 at 13:24
  • [Authorize] checked the User.IsAuthorized - But there is no user at all - So adding [Authorize] to controllers just prevents me from accessing the controller and returns a 404 Commented Apr 1, 2020 at 13:49
  • I just copied the code snippets above to a new Web Api project template, generated a cookie, and when I sent the cookie back, the HttpContext.User ClaimsPrincipal was correctly populated with the claims set previously. So I cannot repro the issue. Do I understand correctly that you're generating a cookie, and then trying to send another request with the cookie included? Because if you're checking in the same request as the sign-in, it won't be populated yet; only when ASP.NET runs authentication on the received cookie. Commented Apr 1, 2020 at 14:40
  • I have a client app (Blazor) and my web API, they are on different ports. First of all I do a request to api/login then (another controller) api/production - This is where I am inspecting the User.Identity - It's not creating the Cookie at all - When I do F12 dev tools, nothing there either Commented Apr 1, 2020 at 14:50
  • Is there any cross-origin setting I need to enable? As they are both on different ports? Commented Apr 1, 2020 at 14:52

1 Answer 1

1

Thanks for your help guys!

I finally realised it was a client thing, I did three things:

  • CORS was an issue, in my .UseCors method call my my Api I allowed credentials: .AllowCredentials()
  • My client app in using Blazor, I found this article here which told me I needed to set the http request configuration to include credentials, so in my client side app startup.cs:
    WebAssemblyHttpMessageHandlerOptions.DefaultCredentials = FetchCredentialsOption.Include;
  • I am using Http not Https on my local, and Chrome was complaining about SameSite, so im my Api StartUp.cs, where I call AddAuthentication...AddCookie I added this: options.Cookie.SameSite = SameSiteMode.Unspecified;

I don't fully understand the SameSite... and I have also come across JSON Web Tokens (JWT).
But I'm not interested, as long as it's working. ;-)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.