在Windows Phone上保留HTTPOnly cookie

Preserving HTTPOnly cookies on Windows Phone
2021-09-15
  •  译文(汉语)
  •  原文(英语)

我有一个通过HTTPS发送用户名和密码到API的应用程序.该API返回HTTPOnly cookie.

这意味着cookie对代码"不可见",但仍然存在,并将在后续请求中发送给服务器.

Set-Cookie报头被从汽提HttpWebResponse.Headers和cookie不出现在HttpWebResponse.CookieS或的HttpWebRequest.CookieContainer.但是,如果使用该请求进行后续请求,则将HttpWebRequest.CookieContainer它们发送到服务器,但是代码无法访问它们.

据我所知,这使得它们无法以任何方式进行序列化或保留.看起来唯一可行的方法是缓存实际的用户名和密码,然后每次再次登录.

我有什么想念的吗?

速聊1:
您可以序列化整个容器CookieContainer(answer.flyppdevportal.com/categories/metro/…),并在需要时重用整个容器吗?
速聊2:
您不能操作httponly cookie.仅当您发送http请求时,才对它们进行修改.这对于服务器与客户端之间的安全通信至关重要.因此,您面临的这种行为是正常的.
速聊3:
如果您对CookieContainer进行序列化,则在未序列化时将不再发送cookie.
速聊4:
我目前正在研究相同的问题.只是为了确保我理解正确:您确实为HttpWebRequest分配了一个新的Cookie容器,并在HttpWebResponse中获得了一个空的CookieContainer.但是,您使用此容器并将其传递给所有后续请求,并且使用了收到的httponly cookie吗?从我的阅读中,我会支持user568109的论点,即不可能对cookie容器内的httponly cookie对象进行调整.这就是为什么它可能总是空的原因:(
速聊5:
NewsBlur API有机会吗?那就是我遇到的地方,我唯一的解决方案是每次应用启动时都登录.我希望很快会转向oauth ...
解决过程1

您必须使用反射来查看存储在cookie容器中的Cookies.

使用类似的东西来查看您拥有的东西,然后您可以尝试通过子类化来访问所需的数据,也可以通过将cookie存储在内存中,从容器中删除它,然后将其添加为的过程来完成.一个普通的cookie

    public List<Cookie> GetAllCookies(CookieContainer cc)
    {
        List<Cookie> lstCookies = new List<Cookie>();

        Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cc, new object[] { });

        foreach (var pathList in table.Values)
        {
            SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { });
            foreach (CookieCollection colCookies in lstCookieCol.Values)
                foreach (Cookie c in colCookies) lstCookies.Add(c);
        }

        return lstCookies;
    }
    public string ShowAllCookies(CookieContainer cc)
    {
        StringBuilder sb = new StringBuilder();
        List<Cookie> lstCookies = GetAllCookies(cc);
        sb.AppendLine("=========================================================== ");
        sb.AppendLine(lstCookies.Count + " cookies found.");
        sb.AppendLine("=========================================================== ");
        int cpt = 1;
        foreach (Cookie c in lstCookies)
            sb.AppendLine("#" + cpt++ + "> Name: " + c.Name + "\tValue: " + c.Value + "\tDomain: " + c.Domain + "\tPath: " + c.Path + "\tExp: " + c.Expires.ToString());

        return sb.ToString();
    }
速聊1:
使用反射访问Windows Phone上的非公共类型时,是否没有获得MethodAccessException?每次我尝试执行此操作都会失败.
速聊2:
接得好.内部和受保护应该可以,但私有绝对不能.查看CookieContainer的源代码,这应该可以工作.如果不是这样,将需要根据源构建自定义cookie容器类,并加以利用.
速聊3:
我什至无法在WP8上编译此代码(缺少Hashtable,SortedList).
速聊4:
-您应该能够轻松修改代码,以使用列表和字典集合.这只是一个例子.概念保持不变.
速聊5:
我不记得任何细节,但是我无法使此代码正常工作.
解决过程2

您也可以尝试使用TCP套接字直接获取cookie.这是我对类似问题的回答:https : //stackoverflow.com/a/21737087/262036

获得响应后,您将解析字符串以搜索cookie并获取值.之后,您可以在CookieContainer中创建一个不是HttpOnly的新cookie,并在下一个请求中使用它.

I have an app that sends a username and password to an API via HTTPS. The API returns HTTPOnly cookies.

This means that the cookies are "invisible" to the code, but still exist and will be sent to the server in subsequent requests.

The Set-Cookie header is stripped from the HttpWebResponse.Headers and the cookie does not appear in the HttpWebResponse.Cookies or the HttpWebRequest.CookieContainer. However, if a subsequent request is made using that same HttpWebRequest.CookieContainer they are sent to the server, but they are inaccessible to the code.

As far as I can tell, this makes them impossible to serialize or preserve in any way. It seems the only way to make this work will be to cache the actual username and password and login again every time.

Is there something I am missing?

Talk1:
Could you serialize the entire CookieContainer (answers.flyppdevportal.com/categories/metro/…) and reuse the entire container when required?
Talk2:
You cannot manipulate httponly cookie. They are modified only when you send http requests. It is essential for secure communication between server and client. So this behaviour you are facing is normal.
Talk3:
If you serialize the CookieContainer, when it is unserialized the cookies are no longer sent.
Talk4:
I'm currently looking into the same problem. Just to be sure that I understand you correctly: You did assign your HttpWebRequest a new Cookie Container and got an empty CookieContainer in your HttpWebResponse. However, you use this container and pass it to all your subsequent Requests and the received httponly cookies are used? From my readings I would support user568109 thesis that it is impossible to temper with the httponly cookie object inside the cookie container. That's why its propably always empty :(
Talk5:
NewsBlur API by any chance? That's where I have run into this, and my only solution was to login every time the app starts. I am hoping that a move to oauth will be made soon...
Solutions1

You'll have to use reflection to take a look at the Cookies stored in the cookie container.

Use something like this to have a look at what you have, then you can either try to subclass to gain access to the data you want or go through the process of storing the cookie in memory, deleting it from the container, then adding it as a normal cookie

    public List<Cookie> GetAllCookies(CookieContainer cc)
    {
        List<Cookie> lstCookies = new List<Cookie>();

        Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cc, new object[] { });

        foreach (var pathList in table.Values)
        {
            SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { });
            foreach (CookieCollection colCookies in lstCookieCol.Values)
                foreach (Cookie c in colCookies) lstCookies.Add(c);
        }

        return lstCookies;
    }
    public string ShowAllCookies(CookieContainer cc)
    {
        StringBuilder sb = new StringBuilder();
        List<Cookie> lstCookies = GetAllCookies(cc);
        sb.AppendLine("=========================================================== ");
        sb.AppendLine(lstCookies.Count + " cookies found.");
        sb.AppendLine("=========================================================== ");
        int cpt = 1;
        foreach (Cookie c in lstCookies)
            sb.AppendLine("#" + cpt++ + "> Name: " + c.Name + "\tValue: " + c.Value + "\tDomain: " + c.Domain + "\tPath: " + c.Path + "\tExp: " + c.Expires.ToString());

        return sb.ToString();
    }
Talk1:
Do you not get a MethodAccessException when using reflection to access non-public types on Windows Phone? Every time I have tried to do this it has failed.
Talk2:
good catch. internal and protected should be OK, but private definitely isn't. Looking at the source for CookieContainer, this should work. If not, it will be a matter of building a custom cookie container class based on the source and leveraging that instead.
Talk3:
I can't even compile this code on WP8 (Hashtable, SortedList are missing).
Talk4:
- You should be able to adapt the code pretty easily to use list and dictionary collections instead. It was just an example. The concept remains the same.
Talk5:
I can't recall any details, but I was not able to make this code working.
Solutions2

You can also try using TCP Sockets to get the cookies directly. Here's my answer for a similar question: https://stackoverflow.com/a/21737087/262036

Once you get the response you parse the string in search for the cookie and grab the value. After that you can create a new cookie in the CookieContainer that is not HttpOnly and use it in next requests.

转载于:https://stackoverflow.com/questions/15560653/preserving-httponly-cookies-on-windows-phone

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入