我可以把一个ASP.Net会话ID在一个隐藏的表单字段? [英] Can I put an ASP.Net session ID in a hidden form field?

查看:201
本文介绍了我可以把一个ASP.Net会话ID在一个隐藏的表单字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用我的ASP.Net网站雅虎上传,雅虎UI库的一部分,允许用户上传文件。对于那些不熟悉,上传工作原理是利用一个Flash小程序来给我过的FileOpen对话框更多的控制。我可以指定文件类型过滤器,允许多个文件被选中,等等。这是伟大的,但它有如下记载的限制:


  

由于已知的Flash漏洞后,上传在Firefox在Windows中运行不发送与上传正确的饼干;而不是发送Firefox的饼干,它发送Internet Explorer的Cookie在各自的领域。作为一种变通方法,我们建议或者使用一个Cookie的上传方法或附加的document.cookie到上传请求。


所以,如果用户在使用Firefox,我不能靠饼干时,他们将文件上传到自己的坚持会话。我需要他们的会议,因为我需要知道他们是谁!作为一种变通方法,我使用的是Application对象正是如此:

 的Guid = UPLOADID Guid.NewGuid();
Application.Add(Guid.ToString(),自定义);

所以,我创建一个唯一的ID,并使用它作为一个键存储在应用程序范围内 Page.User 对象。包括我在文件上载该ID作为POST的变量。然后,在接受文件上传的处理程序,我抢用户对象正是如此:

 的IPrincipal用户=(的IPrincipal)应用[的Request.Form [UPLOADID]];

这实际工作,但它有两个明显的缺点:


  • 如果IIS,应用程序池,甚至只是被用户访问上传页面,而实际上的时间之间重新启动应用程序上传文件,他们的UPLOADID从适用范围中删除,并上传失败,因为我不能验证他们的身份。


  • 如果我曾经扩展到Web场(甚至可能是Web园)的情况下,这将彻底打破。我可能不会担心,但我不打算扩展这个应用程序在未来。


有没有人有更好的办法?有没有办法让我传递一个POST变量的实际ASP.Net会话ID,然后使用该ID在另一端检索会话?

我知道我能打通 Session.SessionID 会话ID,我知道如何使用YUI将其发布到下一个页面。我不知道如何使用的SessionID 从状态服务器抓取会话。

是的,我使用状态服务器存储会话,所以他们坚持应用/ IIS重新启动,并且会在Web场方案工作。


解决方案

这里是一个职位从 SWFUpload的维护者解释如何从存储在的Request.Form一个ID加载了会议。我想同样的事情会在雅虎工作的组成部分。

请注意安全免责声明岗位的底部。



  

将Global.asax文件及以下code可以覆盖丢失的会话ID的Cookie:


 使用系统;
使用的System.Web;公共类Global_asax:System.Web.HttpApplication
{
    私人无效的Application_BeginRequest(对象发件人,EventArgs的发送)
    {
        / *
        修正了在非IE浏览器的Flash播放器的Cookie错误。
        由于Flash播放器总是在Firefox甚至发送IE的cookie
        我们已经通过作为POST的一部分或GET发送值绕过饼干
        并覆盖在价值传递的cookie。        该理论认为,在这一点(的BeginRequest)饼干都没有已经准备好了
        会话和验证逻辑,如果我们在这里更新饼干,我们会得到我们的
        会话和验证正确还原
        * /        HTT prequest请求= HttpContext.Current.Request;        尝试
        {
            字符串sessionParamName =ASPSESSID;
            字符串sessionCookieName =ASP.NET_SESSIONID;            字符串sessionValue = REQUEST.FORM [sessionParamName]?的Request.QueryString [sessionParamName]
            如果(sessionValue!= NULL)
            {
                UpdateCookie(sessionCookieName,sessionValue);
            }
        }
        赶上(异常前)
        {
            // TODO:添加日志记录在这里。
        }        尝试
        {
            字符串authParamName =AUTHID;
            字符串authCookieName = FormsAuthentication.FormsCookieName;            字符串authValue = REQUEST.FORM [authParamName]?的Request.QueryString [authParamName]
            如果(authValue!= NULL)
            {
                UpdateCookie(authCookieName,authValue);
            }
        }
        赶上(异常前)
        {
            // TODO:添加日志记录在这里。
        }
    }    私人无效UpdateCookie(字符串cookieName,串cookieValue)
    {
        的HttpCookie饼干= HttpContext.Current.Request.Cookies.Get(cookieName);
        如果(饼干== NULL)
        {
            的HttpCookie newCookie =新的HttpCookie(cookieName,cookieValue);
            Response.Cookies.Add(newCookie);
        }
        其他
        {
            cookie.Value = cookieValue;
            HttpContext.Current.Request.Cookies.Set(饼干);
        }
    }
}


  

安全警告:不要只是复制并粘贴此code到您的ASP.Net应用程序不知道自己在做什么。它引入了安全问题和跨站点脚本的可能性。


I'm using the Yahoo Uploader, part of the Yahoo UI Library, on my ASP.Net website to allow users to upload files. For those unfamiliar, the uploader works by using a Flash applet to give me more control over the FileOpen dialog. I can specify a filter for file types, allow multiple files to be selected, etc. It's great, but it has the following documented limitation:

Because of a known Flash bug, the Uploader running in Firefox in Windows does not send the correct cookies with the upload; instead of sending Firefox cookies, it sends Internet Explorer’s cookies for the respective domain. As a workaround, we suggest either using a cookieless upload method or appending document.cookie to the upload request.

So, if a user is using Firefox, I can't rely on cookies to persist their session when they upload a file. I need their session because I need to know who they are! As a workaround, I'm using the Application object thusly:

Guid UploadID = Guid.NewGuid();
Application.Add(Guid.ToString(), User);

So, I'm creating a unique ID and using it as a key to store the Page.User object in the Application scope. I include that ID as a variable in the POST when the file is uploaded. Then, in the handler that accepts the file upload, I grab the User object thusly:

IPrincipal User = (IPrincipal)Application[Request.Form["uploadid"]];

This actually works, but it has two glaring drawbacks:

  • If IIS, the app pool, or even just the application is restarted between the time the user visits the upload page, and actually uploads a file, their "uploadid" is deleted from application scope and the upload fails because I can't authenticate them.

  • If I ever scale to a web farm (possibly even a web garden) scenario, this will completely break. I might not be worried, except I do plan on scaling this app in the future.

Does anyone have a better way? Is there a way for me to pass the actual ASP.Net session ID in a POST variable, then use that ID at the other end to retrieve the session?

I know I can get the session ID through Session.SessionID, and I know how to use YUI to post it to the next page. What I don't know is how to use that SessionID to grab the session from the state server.

Yes, I'm using a state server to store the sessions, so they persist application/IIS restarts, and will work in a web farm scenario.

解决方案

Here is a post from the maintainer of SWFUpload which explains how to load the session from an ID stored in Request.Form. I imagine the same thing would work for the Yahoo component.

Note the security disclaimers at the bottom of the post.


By including a Global.asax file and the following code you can override the missing Session ID cookie:

using System;
using System.Web;

public class Global_asax : System.Web.HttpApplication
{
    private void Application_BeginRequest(object sender, EventArgs e)
    {
        /* 
        Fix for the Flash Player Cookie bug in Non-IE browsers.
        Since Flash Player always sends the IE cookies even in FireFox
        we have to bypass the cookies by sending the values as part of the POST or GET
        and overwrite the cookies with the passed in values.

        The theory is that at this point (BeginRequest) the cookies have not been ready by
        the Session and Authentication logic and if we update the cookies here we'll get our
        Session and Authentication restored correctly
        */

        HttpRequest request = HttpContext.Current.Request;

        try
        {
            string sessionParamName = "ASPSESSID";
            string sessionCookieName = "ASP.NET_SESSIONID";

            string sessionValue = request.Form[sessionParamName] ?? request.QueryString[sessionParamName];
            if (sessionValue != null)
            {
                UpdateCookie(sessionCookieName, sessionValue);
            }
        }
        catch (Exception ex)
        {
            // TODO: Add logging here.
        }

        try
        {
            string authParamName = "AUTHID";
            string authCookieName = FormsAuthentication.FormsCookieName;

            string authValue = request.Form[authParamName] ?? request.QueryString[authParamName];
            if (authValue != null)
            {
                UpdateCookie(authCookieName, authValue);
            }
        }
        catch (Exception ex)
        {
            // TODO: Add logging here.
        }
    }

    private void UpdateCookie(string cookieName, string cookieValue)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookieName);
        if (cookie == null)
        {
            HttpCookie newCookie = new HttpCookie(cookieName, cookieValue);
            Response.Cookies.Add(newCookie);
        }
        else
        {
            cookie.Value = cookieValue;
            HttpContext.Current.Request.Cookies.Set(cookie);
        }
    }
}

Security Warning: Don't just copy and paste this code in to your ASP.Net application without knowing what you are doing. It introduces security issues and possibilities of Cross-site Scripting.

这篇关于我可以把一个ASP.Net会话ID在一个隐藏的表单字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆