[C#]使用 HttpWebRequest 浏览整合式 windows 认证环境的网站

使用 HttpWebRequest 浏览整合式 windows 认证环境的网站


一般来说,企业为了保密,或是避免员工乱来,
通常在公司电脑有做权限的管理,
常见的就是加入网域,走 Proxy 之类的作法,
员工电脑必须在网域下输入账号密码才能进到 Windows。

上面讲的跟主题有啥关系勒?
最近碰到的一个问题就出在这,
看下图比较快:


[C#]使用 HttpWebRequest 浏览整合式 windows 认证环境的网站

因为某些需求,当使用者在浏览特定页面的时候,例如页面A;
会去触发注册在页面A上的一个使用者控件,(我比较喜欢称为组件)
然后我们在控件中加入 HttpWebRequest/Response,
让程序“偷偷的”去浏览页面B,
之所以会写“偷偷的”,是因为控件会去创造类似虚拟浏览器的环境,
去浏览并接受特定网址回传的消息,
由于这个动作是使用者不知情的(幕后执行),所以用“偷偷的”来形容。



网友看到这边可能会有疑问…那为何页面B要执行的程序不写在页面A就好?
还要如此大费周章?
这部分牵涉到页面A重复使用性的问题,因为页面A是同时给很多不同 Case 的使用者去浏览的,
而每个Case 要去触发的状况又不一样,所以不能全写死在程序中。
例如:使用者1浏览页面A时,要幕后触发的是页面C,
使用者2浏览页面A时,要幕后触发的反而是页面D。



写完后,那程序应该可以 run 了吧?
但问题总出在令人意料不到的环节上:


[C#]使用 HttpWebRequest 浏览整合式 windows 认证环境的网站

没错,就是有问题!
就在我把页面A打开的时候,出现了上图的错误消息,
关键就在 HttpWebRequest 所执行的身份以及授权。



其实当我们利用 Browser 浏览网站时,Browser 已经事先帮我们做了很多事情,
特别是在整合式 windows 认证环境的页面,如果使用者是有登录网域的,
则对使用者来说丝毫不会有任何差异,因为Browser 已经帮你完成认证了。
但是 HttpWebRequest 就不一样了,它是程序创造出来的虚拟浏览器,
完全没有任何权限,这将导致它在浏览一些非匿名存取的网站时,就会出现上面的错误。



先来看一下程序,标准 MSDN 的写法:
01 void MailSenderTrigger(string btNo)
02 ...{
03 try
04 ...{
05 string URL = "http://www.urWebName.com/"; //欲浏览的特定页面
06
07 //初始化 HttpWebRequest
08 HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
09
10 // 设定内容类型
11 myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
12
13  //初始化 HttpWebResponse
14 HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
15 Stream msgstream = myHttpWebResponse.GetResponseStream(); //接收回传消息
16
17 Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); //设定编码方式
18
19 //用 StreamReader 读出回传消息
20 StreamReader readStream = new StreamReader(msgstream, encode);
21
22 string Syslog = "";
23 Syslog = readStream.ReadToEnd();
24 readStream.Close();
25 }
26 catch (Exception e3)
27 ...{
28 Response.Write(e3.ToString());
29 }
30 }

爬了一下文之后,找到好几种解决的方法,
例如将页面设定为可匿名存取(可以过,但是一般不建议这样的方式),
或是在 web.config 中加入:(试过还是不行)

1

最后找到的解法是在 GetResponse() 之前加上这一段:

1 myHttpWebRequest.Credentials = CredentialCache.DefaultCredentials;

这样就可以用当时使用者当时登录的身份进行认证,
另外,DefaultCredentials 只记录了程序运行时的一些认证消息,
而不会纪录使用者的账号和密码,所以对安全性来说有一定帮助,
如果硬要检视详细的内容,也只会得到一堆空字符串,
这或许也是微软的保护机制吧!?



如果你要指定一个身份去登录网站的话,可以这样做:

1 myHttpWebRequest.PreAuthenticate = true;
2 NetworkCredential netCreden=new NetworkCredential("userName", "userPW"); //登入的账号密码
3 myHttpWebRequest.Credentials = netCreden.GetCredential(new Uri(URL), "authType"); //要浏览的网址以及认证类型
4

当然,如果你的认证方式是默认值且网址URL跟最前面相同的话,
最后一行可以简写为

1 myHttpWebRequest.Credentials=netCreden;

原文:大专栏  [C#]使用 HttpWebRequest 浏览整合式 windows 认证环境的网站


上一篇:通常如何在iBatis中使用mysql的限制?


下一篇:sql学习第一天--sql简介