Search code examples
cookiesasp.net-core-mvcasp.net-core-6.0claims-authenticationcookie-path

How to set path for authentication cookie


In ASP.NET Core 6 MVC multi-tenant application tenants have different path base like /tenant1 and /tenant2.

Middleware sets HttpContext PathBase from request url.

SignInAsync method always sets authentication cookie path to the root path /.

I'm trying to set authentication cookie path from PathBase using this code snippet:

Path = Request.PathBase.HasValue ? Request.PathBase.Value : "/"

The code shown below throws a compile-time error since AuthenticationProperties does not have a Path property. How to set cookie Path property so that different users can authenticated with different base paths?

public class AccountController : Controller 
{
    public async Task<IActionResult> LogOn(string user, string password)
    {
        if (password != "secret")
            throw new ApplicationException("Bad password");

        var claims = new List<Claim> { new Claim(ClaimTypes.Name, user) };
        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
        var authProperties = new AuthenticationProperties 
                                 {
                                     IsPersistent = true,
                                     AllowRefresh = true,
                                     // TODO: this throws compile error since Path property does not exist
                                     Path = Request.PathBase.HasValue ? Request.PathBase.Value : "/"
                                 };
    
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
    }
}

Solution

  • You should be able to achieve this by writing your own ICookieManager and setting it when adding cookie authentication scheme. ICookieManager methods get HttpContext as input so you have access to PathBase from there.

    builder.Services.AddAuthentication()
        .AddCookie("Cookie", options =>
    {
        options.CookieManager = CustomCookieManager();
    });
    

    Here's the default implementation of ICookieManager : ChunkingCookieManager