IdentityServer与Cookie的Samesite

在使用IdentityServer时遇到Chrome浏览器登录失败,原因是Chrome要求'SameSite=None'的Cookie必须通过HTTPS设置。解决方案包括切换到HTTPS或在非HTTPS环境中修改Cookie设置,使其在非安全连接下不使用'SameSite=None'属性。了解'SameSite'的严格、宽松和无模式,以及IdentityServer为何选择无模式来确保跨域Cookie传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在使用IdentityServer的时候碰到谷歌浏览器无法登录的问题,查看网络发现如下错误提示:

The Set-Cookie was blocked because it had the “SameSite=None” attribute but did not have the secure attribute, which is required in order to use “SameSite=None”

原因是因为IdentityServer在写Cookie的时候使用的是SameSite=None属性,但是谷歌浏览器(大概是从版本80几开始)要求必须是HTTPS才能使用该属性,所以如果使用的是非HTTPS连接,那么就会碰到无法登录的问题。

当然最简单的解决办法就是使用HTTPS,毕竟IdentityServer是用来做认证的,理应使用更安全的HTTPS连接。

但是有些特殊情况,比如局域网内用IP地址访问的时候,应该怎么办呢?

其实我们可以通过修改Cookie的写入决策,在非HTTPS连接的时候移除SameSite属性即可。

修改Startup文件如下:

private const SameSiteMode Unspecified = (SameSiteMode)(-1);

public void ConfigureServices(IServiceCollection services)
{
    //配置Cookie决策
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.MinimumSameSitePolicy = Unspecified;
        options.OnAppendCookie = cookieContext =>
            SetSameSite(cookieContext.Context,cookieContext.CookieOptions);
        options.OnDeleteCookie = cookieContext =>
            SetSameSite(cookieContext.Context, cookieContext.CookieOptions);
    });

    //other service
}

public void SetSameSite(HttpContext httpContext, CookieOptions options)
{
    if (options.SameSite == SameSiteMode.None)
    {
        //检测如果不是HTTPS,则移除SameSite属性
        if (httpContext.Request.Scheme != "https")
        {
            //设置为Unspecified,则不会添加SameSite属性
            options.SameSite = Unspecified;
        }
    }
}


public void Configure(IApplicationBuilder app)
{
    if (Environment.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    //使用Cookie决策
    app.UseCookiePolicy();
    
    //other middleware
}

关于SameSite,我们可以在Mozilla找到相关定义:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

这里也有篇很好的解释:
https://web.dev/samesite-cookies-explained/

简单点讲,她主要用来在请求URL的时候,控制浏览器是否接受和发送cookie, 有三个属性值:

  • Strict: 最严格模式,只有请求的地址和浏览器的地址在同一个域名的时候,才会接受和发送Cookie。
  • Lax:宽松模式,同一个域名会接受和发送,如果不在同一个域名,但是请求的地址为GET请求时,也会接受和发送Cookie,其他请求(POST,IFrame,Ajax,Image等)不会接受和发送cookie。
  • None:始终接受和发送Cookie,但是对于谷歌浏览器来说,要求必须是HTTPS连接(估计以后其他浏览器也会跟进)。

IdentityServer为什么会使用None而不使用更为严格的Strict,Lax模式呢?

回顾前几篇关于Blazor与IdentityServer集成的例子

登录成功之后,我们查看Blazor页面的源代码,会看到如下iframe:

在这里插入图片描述

这是属于IdentityServer的地址,用来检查用户是否在线,显然她是需要发送Cookie的,所以只能使用SameSite=None。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值