question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Bug] Can't set SameSite=None for cross-site cookie use

See original GitHub issue

Which Version of Microsoft Identity Web are you using ? Note that to get help, you need to run the latest version. Microsoft Identity Web 0.1.4-preview

Where is the issue?

  • Web App
    • Sign-in users
    • Sign-in users and call web APIs
  • Web API
    • Protected web APIs (Validating tokens)
    • Protected web APIs (Validating scopes)
    • Protected web APIs call downstream web APIs
  • Token cache serialization
    • In Memory caches
    • Session caches
    • Distributed caches

Other? - please describe; Unsure if this is a bug or just wrong setup.

Is this a new or existing app? I am trying to set SameSite=None for cross-site cookie use in accordance with https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1 or https://docs.microsoft.com/en-us/aspnet/core/security/samesite/rp31?view=aspnetcore-3.1. However, I can’t change the default behaviour of “.AspNetCore.Cookies”. I can rename the cookie using the cookieScheme parameter of AddSignIn, but if I try to alter it in any other way I get “System.InvalidOperationException: Scheme already exists: Cookies”.

Repro

  1. Setup https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-2-B2C in accordance with guidelines
  2. Set SameSite=None for cross-site cookie use in accordance with https://docs.microsoft.com/en-us/aspnet/core/security/samesite/rp31?view=aspnetcore-3.1
  3. Run the client
            services.AddDistributedMemoryCache();

            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                //options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
                // SAMESITE CODE START
                options.MinimumSameSitePolicy = SameSiteMode.None;
                options.Secure = CookieSecurePolicy.Always;
                // SAMESITE CODE END
                // Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
                options.HandleSameSiteCookieCompatibility();
            });

            services.AddOptions();

            services.AddSignIn(Configuration, "AzureAdB2C")
                // SAMESITE CODE START
                .AddAuthentication()
                .AddCookie(options =>
                {
                    options.Cookie.SameSite = SameSiteMode.None;
                    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
                    options.Cookie.IsEssential = true;
                })
                // SAMESITE CODE END
                ;

            // This is required to be instantiated before the OpenIdConnectOptions starts getting configured.
            // By default, the claims mapping will map claim names in the old format to accommodate older SAML applications.
            // 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' instead of 'roles'
            // This flag ensures that the ClaimsIdentity claims collection will be built from the claims in the token
            // JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

            // Token acquisition service based on MSAL.NET
            // and chosen token cache implementation
            services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { Configuration["TodoList:TodoListScope"] }, configSectionName: "AzureAdB2C")
                    .AddInMemoryTokenCaches();

Expected behavior Can use cross-site cookies use as expected. Ie. the cookie of interest has SameSite=None and being Secure.

Actual behavior Gets an exception: “System.InvalidOperationException: Scheme already exists: Cookies”

Possible Solution

Additional context/ Logs / Screenshots Add any other context about the problem here, such as logs and screenshots.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
SteinLTcommented, Jun 12, 2020

@jmprieur : thanks for the response. As far as I can tell from that code it ensures backward compatibility with older browsers and assumes that the cookie of interest is already set to SameSite=None. However, the default behavior for Cookie Authentication, the specific “.AspNetCore.Cookies” cookie set by the AddSignIn method in this case, is SameSite=Lax (according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1 also observed using the Inspect dev tool found in most browsers), and hence HandleSameSiteCookieCompatibility() doesn’t work in this case.

However, I have modified the sniffing method somewhat

private static void CheckSameSite(HttpContext httpContext, CookieOptions options, Func<string, bool> disallowsSameSiteNone)
{
    // A hack to ensure that the authentication cookie “.AspNetCore.Cookies” is set to SameSite=None
    if (options.SameSite == SameSiteMode.Lax && options.Secure)
    {
        options.SameSite = SameSiteMode.None;
    }
    // End of hack
            
    if (options.SameSite == SameSiteMode.None)
    {
        var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
        if (disallowsSameSiteNone(userAgent))
        {
            options.SameSite = SameSiteMode.Unspecified;
        }
    }
}

It is not ideal but does the job in my case. Is this now the official approach for setting the authentication cookie “.AspNetCore.Cookies” to SameSite=None?

0reactions
jmprieurcommented, Jul 15, 2020

Closing as the question was answered. See also https://github.com/AzureAD/microsoft-identity-web/wiki/SameSite-Cookies

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why won't cross site cookies be sent even with https ...
I'm creating a proof of concept to use cookie authentication with jwt's in aspnet core with a separate UI server (i.e. the UI...
Read more >
How to handle SameSite cookie changes in Chrome browser
SameSite is a property that can be set in HTTP cookies to prevent Cross Site Request Forgery(CSRF) attacks in web applications:.
Read more >
Cross-Site Cookies Will Now Be Rejected on localhost ...
The new rule demands that all cross-site cookies set in a browser have to be set with Secure attribute if they are to...
Read more >
Get Ready for New SameSite=None; Secure Cookie Settings
Developers must use a new cookie setting, SameSite=None , to designate cookies for cross-site access. When the SameSite=None attribute is present, ...
Read more >
Understanding SameSite cookies
The one advantage of SameSite=None is that cookies are always sent, so if you need a cookie to be sent cross site, it's...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found