1

I have an ASP.NET core backend and the frontend is written in Blazor (Blazor WebAssembly). When I start my backend the frontend is started as well and both run under https://localhost:5000. When I log in the user with the SignInManager the framework correctly sets the Set-Cookie header in the response and the browser correctly sets the cookie and it is an authenticated session from now on.
However, I sometimes start the frontend with the command dotnet watch run separately so I have a better "Edit and continue" experience. Started like this, the frontend runs under https://localhost:7026 and requests against the backend running under https://localhost:5000. This works. Requests work, CORS is set up and the backend is reachable. With that setup, the frontend running under :7026, when I login the user, the framework again correctly sets the Set-Cookie Header in the Response but the browser does not set the application cookie.
What I did notice, is that when the user is signed in from the frontend running under :5000 the cookie is also set for the frontend running under :7026 but the browser does not send that cookie with the requests, thus resulting in an unauthenticated session for the frontend running under :7026.

I did read that cookies should be port agnostic so I am wondering why the browser does not set the cookie when the frontend runs under :7026.
Cookie config:

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
    options.ExpireTimeSpan = TimeSpan.FromDays(5);
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;

    options.Events = new CookieAuthenticationEvents
    {
        OnRedirectToLogin = context =>              {
            if (context.Request.Path.StartsWithSegments("/api"))
            {
                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            }
            return Task.CompletedTask;
        }
    };
});

Cors:

builder.Services.AddCors(
    options => options.AddDefaultPolicy(
        policy => policy.WithOrigins("https://localhost:7026").AllowAnyMethod().AllowAnyHeader().AllowCredentials()));

//request pipeline
app.UseRouting();

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

app.UseCors();
//shortened for brevity...

I tried:

  1. Different Cookie.SameSite policies
  2. Different Cookie.SecurePolicy policies
  3. Setting Cookie.Domain to specific domain
  4. Reinstalling the self signed asp.net core certificate to run localhost under https

None of those resulted in having the cookie correctly set when the frontend runs under :0726 and the backend under :5000

  • localhosts on different ports are treated as different domains.... so maybe this is a CORS issue. One way to test this is to launch the browser with CORS turned off: https://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome If these are JS calls you might also check your withCredentials attribute... that should be true for cookies to be sent methinks... – pcalkins Aug 17 '23 at 17:00
  • but I would get a CORS error in the console, right? Which I don't. That is why I ruled out a CORS issue. But if it is silent it still could be? I think these are not JS calls as the FE is written in Blazor but I am not 100% sure what happens down under the inside the framework. – Stefan Grasböck Aug 17 '23 at 18:53
  • yes, seems like you'd get a CORS error, but it's worth a check. I'm not real sure that cookies are always port agnostic though... since localhosts on different ports are treated as different domains, I wouldn't be surprised if the browser wouldn't set or send them either if the origin's port didn't match... this may be a special case for local ips... – pcalkins Aug 17 '23 at 19:06
  • Testing this a little more, I do see the cookies I set in developer tools WITH the port# when I'm running from localhost. When I go to the release server the cookies are set without the port#. That suggests to me that port may be an issue on localhost.... cookies set from the front-end will be set with front-end's port... set from back-end with back-end's port. For Chrome check F12->Application->Storage to see what cookies are set... it may just be that they aren't sent with Blazor requests. – pcalkins Aug 17 '23 at 19:27
  • But if I set the SameSite policy to Lax/None shouldn't that have resolved the issue then? I think i missing something basic here? – Stefan Grasböck Aug 17 '23 at 19:28
  • see if they are set in the browser first... it could be that you just need to set Blazor to sendCredentials with the request. (Not sure what options that is in blazor as I've never used it.) You should also know that only cookies matching the domain being accessed will be sent with the request... that's not a CORS rule, it's just the way cookies work. (Otherwise the browser would be sending all cookies ever set in the browser with every request...) So cookies set from local-side may not be sent to server-side (which is effectively a different domain.. same-site doesn't affect that) – pcalkins Aug 17 '23 at 19:48
  • it is all confusing... but basically same-site flag affects if the cookies stored in the browser that match the destination domain of the request are sent when the request is made cross-site (from one domain to another domain... the cookies still have to match to destination domain) – pcalkins Aug 17 '23 at 20:07
  • There seems to be a similar question in this [link](https://stackoverflow.com/questions/39370019/how-set-cookie-sent-from-server-to-a-client-on-a-different-port) – Xinran Shen Aug 18 '23 at 05:57

0 Answers0