IE或“边缘打印”对话框将请求发送到没有会话的服务器(因为SameSite =会话cookie松懈)

时间:2019-12-03 06:55:41

标签: internet-explorer cookies microsoft-edge printdialog samesite

我有一个asp.net网站,用户可以登录,成员可以通过Ctrl + P获取报告或打印页面。

最近,当我的成员在IE中打开我的网站并尝试打印时,他们已注销!

为什么? 因为IE打印对话框会向服务器发送一些没有会话cookie的请求,所以StateServer为此客户端释放新会话,然后用户注销。

为什么打印对话框发送了请求? 我不知道,但是我想IE打印对话框会尝试渲染页面并准备打印。

为什么打印对话框未发送当前会话cookie? 由于.net的新更新为会话cookie设置SameSite = lax,因此来自打印对话框的请求无法发送当前会话cookie。 https://support.microsoft.com/en-us/help/4524419/kb4524419

如何防止IE打印对话框发送请求? 或如何强制IE打印对话框发送相同的会话cookie?

有什么主意吗?

已编辑: 我创建一个示例项目来显示此问题。您可以下载我的项目并在IIS上托管,然后打开Default.Aspx并尝试在IE(或Edge)中打印该页面。 您会看到我的问题。 https://easyupload.io/w6vvpy

3 个答案:

答案 0 :(得分:1)

我确认了这个问题。目前,作为一种解决方法,一旦删除SameSite属性,问题就消失了。这不是最佳解决方案,但似乎目前可以使用。

var cookies = this.Response.Cookies;
FormsAuthentication.SetAuthCookie( "JohnDoe", rememberMe );
var allCookies = cookies.AllKeys.Select( key => cookies[key] ).ToList();
allCookies.ForEach( cookie => cookie.SameSite = (SameSiteMode)(-1) );

在ASP.NET Core 3.0和更高版本中,更改了SameSite默认设置,以避免与不一致的客户端默认设置冲突。以下API已将默认值从SameSiteMode.Lax更改为-1,以避免为这些cookie发出SameSite属性

https://docs.microsoft.com/en-us/aspnet/core/security/samesite

我们所做的是创建了HttpModule,该模块在响应中查找cookie并进行相应的修改。

答案 1 :(得分:1)

找到了解决方法:

您必须在会话状态标记中设置cookieSameSite= "None",以避免出现此问题。我已经尝试过了,并且在所有浏览器中都能正常工作。

<sessionState cookieSameSite="None" cookieless="false" timeout="360">
</sessionState>

答案 2 :(得分:0)

我已经重现了这个问题,看来当我们打印页面时,它将调用DownloadHandler加载图像。目前,由于会话为null,因此图像将不会显示。

要解决此问题,建议您尝试使用QueryString方法(而不是使用会话状态)将登录状态转移到DownloadHandler。

请尝试如下修改您的代码:

Default.aspx

<img src="" runat="server" id="image" />

Default.aspx.cs

    protected void Page_Load(object sender, EventArgs e)
    {
        //check whether user login or not
        if (Session["LoginOK"] != null)
        {
            this.Title = "SessionID: " + Session.SessionID;
            //set the image control resource according the session value.
            image.Src = "./DownloadHandler.ashx?LoginOK=" + Session["LoginOK"].ToString();
        }
        else
        {
            //redirect to the login page 
            //after that, set the session value.
            Session["LoginOK"] = true;
            image.Src = "./DownloadHandler.ashx?LoginOK=true";
        }
    }

DownloadHandler:

        bool.TryParse(context.Request.QueryString["LoginOK"]?.ToString(), out bool hasAccess);

        if (!hasAccess)
        {
            context.Response.Redirect("./Error.aspx");
            return;
        }

使用上面的代码,当单击打印选项时,它还会向DownLoadHandler发送一个请求,但是我们可以根据查询字符串来加载图像。打印完网页后,我们仍然可以在主页上使用session["LoginOK"](默认)(如果会话未过期)。