2

我有一个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(或边缘)中打印该页面。你会看到我的问题。 https://easyupload.io/w6vvpy

4

3 回答 3

1

找到了修复:

您必须cookieSameSite= "None"在会话状态标签中设置 以避免此问题。我已经尝试过了,并且在所有浏览器中都运行良好。

<sessionState cookieSameSite="None" cookieless="false" timeout="360">
</sessionState>
于 2020-02-20T08:50:37.103 回答
1

I confirm the issue. For now as a workaround, the problem disappears once SameSite attribute gets removed. This is not optimal solution, but seems to work for now.

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) );

In ASP.NET Core 3.0 and later the SameSite defaults were changed to avoid conflicting with inconsistent client defaults. The following APIs have changed the default from SameSiteMode.Lax to -1 to avoid emitting a SameSite attribute for these cookies

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

The thing that we did was, created HttpModule which looks for cookies in the response and modifies them accordingly.

于 2020-01-15T09:32:42.013 回答
0

我已经重现了这个问题,好像我们打印页面的时候,会调用DownloadHandler来加载图片。此时,由于会话为空,所以图像不会显示。

为了解决这个问题,我建议您可以尝试使用 QueryString 方法将登录状态传输到 DownloadHandler,而不是使用会话状态。

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

默认.aspx

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

默认.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";
        }
    }

下载处理程序:

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

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

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

于 2019-12-26T07:16:39.360 回答