网站的Cookie管理除了限定Domain增强安全性之外,.net 2.0新增一个Cookie属性HttpOnly。很棒!
在做一个cookie功能时用到了Cookie的一个属性HttpOnly
Code
HttpCookie a = new HttpCookie("TestName", "TestValue");
a.Domain = ".test.com";
a.HttpOnly = true;
Response.Cookies.Add(a);
原以为这样后,客户端应该无法访问该Cookie了!
结果,如图
感觉比较诡异,于是再查MSDN
得知原来有两个cookie类。System.Web.HttpCookie 类 和 System.Net.Cookie 类
注意命名空间不同。
两个类的说明分别如下:
Cookie 类提供一组用于管理 Cookie 的属性和方法。无法继承此类。
命名空间:System.Net
HttpCookie 类提供创建和操作各 HTTP Cookie 的类型安全方法。命名空间:System.Web
两个类都有HttpOnly属性,分别说明如下:
Cookie.HttpOnly 属性注意:此属性在 .NET Framework 2.0 版中是新增的。确定页脚本或其他活动内容是否可访问此 Cookie。
HttpCookie.HttpOnly 属性注意:此属性在 .NET Framework 2.0 版中是新增的。获取或设置一个值,该值指定 Cookie 是否可通过客户端脚本访问。
问题来了,关键的理解点在于通过什么东东来访问。
不太理解微软机器翻译的“页脚本或其他活动内容”究竟指什么玩意?
于是做测试,建立一个Web Application,
在TestCookie.aspx页面,的Page_Load事件中加入
Code
// Response.Cookies.Clear();
//System.Web.HttpCookie;
HttpCookie a = new HttpCookie("TestName", "TestValue");
//a.Domain = Request.ServerVariables["HTTP_HOST"];
a.HttpOnly = false;
Response.Cookies.Add(a);
HttpCookie b = new HttpCookie("TestB", "TestB");
b.HttpOnly = true;
//b.Domain = Request.ServerVariables["HTTP_HOST"];
Response.Cookies.Add(b);
Response.Write("System.Web.HttpCookie;------------<br/>");
for (int i = 0; i < Request.Cookies.Count; i++)
{
HttpCookie cook = Request.Cookies[i];
Response.Write("<Br/>");
Response.Write("Cookie:");
Response.Write(string.Format("{0} = {1}", cook.Name, cook.Value)+"<Br/>");
//Response.Write(string.Format("Domain: {0}", cook.Domain) + "<Br/>");
Response.Write(string.Format("Path: {0}", cook.Path) + "<Br/>");
Response.Write(string.Format("Secure: {0}", cook.Secure) + "<Br/>");
Response.Write(string.Format("HttpOnly: {0}", cook.HttpOnly) + "<Br/>");
}
//
//System.Net.CookieContainer CookieContainerObject = new System.Net.CookieContainer();
System.Net.CookieCollection CookieCollectionObject = new System.Net.CookieCollection();
System.Net.Cookie a2 = new System.Net.Cookie("TestName2", "TestValue2");
a2.HttpOnly = false;
a2.Domain = Request.ServerVariables["HTTP_HOST"];
//CookieContainerObject.Add(a2);
CookieCollectionObject.Add(a2);
System.Net.Cookie b2 = new System.Net.Cookie("TestB2", "TestB2");
b2.HttpOnly = true;
b2.Domain = Request.ServerVariables["HTTP_HOST"];
//CookieContainerObject.Add(b2);
CookieCollectionObject.Add(b2);
Response.Write("<Br/>");
Response.Write("System.Net.Cookie;*********************<br/>");
foreach (System.Net.Cookie ck in CookieCollectionObject)
{
Response.Write("<Br/>");
Response.Write("Cookie:");
Response.Write(string.Format("{0} = {1}", ck.Name, ck.Value) + "<Br/>");
//Response.Write(string.Format("Domain: {0}", ck.Domain) + "<Br/>");
Response.Write(string.Format("Path: {0}", ck.Path) + "<Br/>");
Response.Write(string.Format("Secure: {0}", ck.Secure) + "<Br/>");
Response.Write(string.Format("HttpOnly: {0}", ck.HttpOnly) + "<Br/>");
}
该段代码的功能主要是测试能否正确读写Cookie
结果如下:
Code
System.Web.HttpCookie;------------
Cookie:TestName = TestValue
Domain: 10.103.33.102:2888
Path: /
Secure: False
HttpOnly: False
Cookie:TestB = TestB
Domain: 10.103.33.102:2888
Path: /
Secure: False
HttpOnly: True
System.Net.Cookie;*********************
Cookie:TestName2 = TestValue2
Domain: 10.103.33.102:2888
Path:
Secure: False
HttpOnly: False
Cookie:TestB2 = TestB2
Domain: 10.103.33.102:2888
Path:
Secure: False
HttpOnly: True
再建一ConSole Application,
看看能否获取并修改该页面的Cookie
代码如下:
Code
string surl = "http://10.103.33.102:2888/TestCookie.aspx";
HttpWebRequest WebRequestObject = (HttpWebRequest)WebRequest.Create(surl);
WebRequestObject.CookieContainer = new CookieContainer();
HttpWebResponse WebResponseObject = (HttpWebResponse)WebRequestObject.GetResponse();
System.Net.CookieCollection CookieCollectionObject = new System.Net.CookieCollection();
// Print the properties of each cookie.
foreach (Cookie cook in WebResponseObject.Cookies)
{
Console.WriteLine("-----------------------System.Web.HttpCookie--------------------------");
Console.WriteLine("Cookie:");
Console.WriteLine("{0} = {1}", cook.Name, cook.Value);
Console.WriteLine("Domain: {0}", cook.Domain);
Console.WriteLine("Path: {0}", cook.Path);
Console.WriteLine("Port: {0}", cook.Port);
Console.WriteLine("Secure: {0}", cook.Secure);
Console.WriteLine("HttpOnly: {0}", cook.HttpOnly);
/**/////// Show the string representation of the cookie.
////Console.WriteLine("String: {0}", cook.ToString());
System.Net.Cookie c = new System.Net.Cookie();
c.Name = cook.Name;
c.Path = cook.Path;
c.HttpOnly = cook.HttpOnly;
c.Domain = cook.Domain;
c.Expires = cook.Expires;
c.Value = cook.Value;
CookieCollectionObject.Add(cook);
}
foreach (System.Net.Cookie ck in CookieCollectionObject)
{
Console.WriteLine("----------------------System.Net.Cookie-------------------------------------");
Console.WriteLine("Cookie:");
Console.WriteLine("{0} = {1}", ck.Name, ck.Value);
Console.WriteLine("Domain: {0}", ck.Domain);
Console.WriteLine("Path: {0}", ck.Path);
Console.WriteLine("Port: {0}", ck.Port);
Console.WriteLine("Secure: {0}", ck.Secure);
Console.WriteLine("HttpOnly: {0}", ck.HttpOnly);
System.Web.HttpCookie c = new System.Web.HttpCookie(ck.Name);
c.Name = ck.Name;
c.Path = ck.Path;
c.HttpOnly = ck.HttpOnly;
c.Domain = ck.Domain;
c.Expires = DateTime.Now.AddDays(1);
c.Value = ck.Value+"--Update";
WebResponseObject.Cookies.Add(ck);
}
foreach (Cookie cook in WebResponseObject.Cookies)
{
Console.WriteLine("-----------------Updateed System.Web.HttpCookie--------------------------");
Console.WriteLine("Cookie:");
Console.WriteLine("{0} = {1}", cook.Name, cook.Value);
Console.WriteLine("Domain: {0}", cook.Domain);
Console.WriteLine("Path: {0}", cook.Path);
Console.WriteLine("Port: {0}", cook.Port);
Console.WriteLine("Secure: {0}", cook.Secure);
Console.WriteLine("HttpOnly: {0}", cook.HttpOnly);
}
运行结果
Code
-----------------------System.Web.HttpCookie--------------------------
Cookie:
TestName = TestValue
Domain: 10.103.33.102
Path: /
Port:
Secure: False
HttpOnly: False
-----------------------System.Web.HttpCookie--------------------------
Cookie:
TestB = TestB
Domain: 10.103.33.102
Path: /
Port:
Secure: False
HttpOnly: True
----------------------System.Net.Cookie-------------------------------------
Cookie:
TestName = TestValue
Domain: 10.103.33.102
Path: /
Port:
Secure: False
HttpOnly: False
----------------------System.Net.Cookie-------------------------------------
Cookie:
TestB = TestB
Domain: 10.103.33.102
Path: /
Port:
Secure: False
HttpOnly: True
-----------------Updateed System.Web.HttpCookie--------------------------
Cookie:
TestName = TestValue
Domain: 10.103.33.102
Path: /
Port:
Secure: False
HttpOnly: False
-----------------Updateed System.Web.HttpCookie--------------------------
Cookie:
TestB = TestB
Domain: 10.103.33.102
Path: /
Port:
Secure: False
HttpOnly: True
请注意, c.Value = ck.Value+"--Update";这句在修改Cookie.value后并没有成功写入该页面的Cookie集合中,换言之,一个未知的客户端应用程序并没有通过读取一个页面的Cookie并修改再写入该页面的Cookie集合。
我的理解是:
1、System.Web.httpCookie主要是服务器端应用。System.Net.Cookie主要是客户端程序应用,后者可以读取前者的Cookie属性和值,而不能修改服务器定义的Cookie。
2、System.Web.httpCookie.HttpOnly=true后,客户端脚本无法访问该Cookie,但其他程序仍然可以访问。
System.Net.Cookie.HttpOnly=true后,因其是客户端程序,故有更多的限制,不允许”页面脚本及其他程序“访问该Cookie, 只有创建它的应用程序可以访问。并且在特定的Domain下。
值得注意的是:HttpOnly属性仅对IE 6 SP1以上的版本才有效,在FireFox3.01下也可以!但对于IE5.x的机器,可能就****
欢迎大伙指正。