您的位置:首页 > 其它

应用程序向IIS传送身份验证[转]

2009-04-17 20:35 453 查看
一、匿名访问........................................................................................................................1

1、客户端发送一个匿名的http请求............................................................................2

2、IIS直接返回请求的页面内容...................................................................................2

二、Windows集成验证........................................................................................................2

1、客户端和服务端机器都在域,客户端以域帐户登录,以服务器名访问......................3

1.1.第一次HttpWebRequest先以匿名发送http请求.........................................3

1.2.服务端返回无授权回应.....................................................................................3

1.3.再次请求,选择Kerberos验证,附带上此用户的验证票.................................3

1.4.服务端验证通过,返回页面..............................................................................4

2、客户端和服务端机器都在域,客户端以域帐户登录,以服务器名访问以外的所有情况5

2.1.第一次HttpWebRequest先以匿名发送http请求.........................................5

2.2.服务端返回无授权回应.....................................................................................5

2.3.HttpWebRequest选择NTLM验证,请求质询码............................................5

2.4.服务器返回质询码............................................................................................5

2.5.HttpWebRequest发送登录本机的账户加密后的质询码..................................5

2.6.服务器通过验证,返回页面..............................................................................6

3、客户端传送定制用户凭据到服务端...........................................................................6

三、基本身份验证.................................................................................................................6

1.1.第一次HttpWebRequest先以匿名发送http请求.........................................7

1.2.服务端返回无授权回应.....................................................................................7

1.3.HttpWebRequest发送base64格式的用户名和密码.....................................7

1.4.服务器通过验证,返回页面..............................................................................7

四、一个应用程序访问webservices的例子........................................................................8

1.1.Webservices端代码......................................................................................8

1.2.Soap调用webservices的格式.....................................................................8

1.3.客户端应用调用webservices代码.................................................................9

前面那篇文章《IIS的各种身份验证详细测试》讨论的是客户端为IE访问IIS的各种身份验证的情况,这篇文章讨论一般应用程序如何应对IIS的各种身份验证,把身份凭据传送到IIS服务端。

无论是访问一般的网页,还是访问webservices,都是通过http协议来完成的,相应的dotnet类库中提供了HttpWebRequest类来实现http的各种访问控制。

一、匿名访问

服务端IIS设置为允许匿名访问,客户端使用HttpWebRequest发送一个get请求,请求一个页面。

//根据需要访问的URL新建HttpWebRequest对象

HttpWebRequestmyHttpWebRequest=(HttpWebRequest)HttpWebRequest.Create("http://192.168.100.82/iisstart.htm");

myHttpWebRequest.Method="GET";

//发送http请求,接收回应到HttpWebResponse对象

HttpWebResponsemyWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse();

//获得http回应的内容部分,是个Stream类型的对象

StreamnewStream=myWebResponse.GetResponseStream();

byte[]byteResponse=newbyte[myWebResponse.ContentLength];

newStream.Read(byteResponse,0,(int)myWebResponse.ContentLength);

//最后把http回应部分内容转成string

stringstrContent=Encoding.UTF8.GetString(byteResponse);

myWebResponse.Close();

抓数据包看这个http的请求和回应过程就是这样的:

1、客户端发送一个匿名的http请求

GET/iisstart.htmHTTP/1.1

Host:192.168.100.82

Connection:Keep-Alive

2、IIS直接返回请求的页面内容

HTTP/1.1200OK

Content-Length:200

Content-Type:text/html

Last-Modified:Fri,23Nov200707:00:18GMT

Accept-Ranges:bytes

ETag:"6084ba819e2dc81:32a"

Server:Microsoft-IIS/6.0

MicrosoftOfficeWebServer:5.0_Pub

X-Powered-By:ASP.NET

Date:Fri,23Nov200707:00:44GMT

<html>

<head>

<metaHTTP-EQUIV="Content-Type"Content="text/html;charset=gb2312">

<titleID=titletext>......</title>

</head>

<bodybgcolor=white>

.Thisisasamplepage!

</body>

</html>

二、Windows集成验证

服务端IIS设置为不允许匿名访问,只选择winodws集成验证,客户端使用HttpWebRequest发送一个get请求,请求一个页面。

要请求需要windows集成验证的资源,前一篇文章已经讨论过,客户端必须选择NTLM或Kerberos这两种验证方式中的一种,传送客户端登录用户的用户凭据到服务端进行验证。

对于NTLM验证来说,客户端使用登录用户的密码派生的key加密服务端发来的质询码,服务端也对质询码做同样的加密处理,两端的加密结果一致,则表明验证通过。

对于Kerberos来说,客户端只发送登录用户的访问这个IIS的验证票,这个验证票只有这个用户和IIS服务器能识别,IIS只凭客户的验证票就可验证用户的身份。

HttpWebRequest的Credentials属性用来承载用户的用户凭据。

CredentialCache类的静态DefaultCredentials属性能够获取运行当前代码的用户系统凭据。

DefaultCredentials属性仅适用于基于NTLM、协商和Kerberos的身份验证。

DefaultCredentials表示运行应用程序的当前安全上下文的系统凭据。对于客户端应用程序,这些通常是运行应用程序的用户的Windows凭据(用户名、密码和域)。DefaultCredentials可以获得用于Kerberos验证的身份验证票,也可以获得用于NTLM验证的当前用户的用户名和密码。

为了在应用程序代码中加上对windows集成验证的支持,只需在上述匿名访问的代码中给HttpWebRequest对象的赋予用户系统凭据即可,HttpWebRequest对象会根据实际情况选择使用哪一种验证方式,并传送相应的用户凭据,在http请求发送出去之前增加以下代码:

myHttpWebRequest.Credentials=CredentialCache.DefaultCredentials;

Windows集成验证,HttpWebRequest对象选择哪种验证方式,基本会出现两种情况:

1、客户端和服务端机器都在域,客户端以域帐户登录,以服务器名访问

1.1.第一次HttpWebRequest先以匿名发送http请求

GET/iisstart.htmHTTP/1.1

Host:logs:81

Connection:Keep-Alive

1.2.服务端返回无授权回应

HTTP/1.1401Unauthorized

Content-Length:1327

Content-Type:text/html

Server:Microsoft-IIS/6.0

WWW-Authenticate:Negotiate

WWW-Authenticate:NTLM

X-Powered-By:ASP.NET

Date:Fri,23Nov200707:22:32GMT

1.3.再次请求,选择Kerberos验证,附带上此用户的验证票

HttpWebRequest首选到AD中查询要访问的服务器是否在域中,如果是在同一域中,则直接发送Kerberos验证的用户验证票。如果服务器不在域中,则会选择NTLM验证。

这里的情况是双方都在域中,选择Kerberos验证。

GET/iisstart.htmHTTP/1.1

Authorization:NegotiateYIIEzQYGKwYBBQUCoIIEwTCCBL2gJDAiBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICCqKCBJMEggSPYIIEiwYJKoZIhvcSAQICAQBuggR6MIIEdqADAgEFoQMCAQ6iBwMFACAAAACjggOiYYIDnjCCA5qgAwIBBaEOGwxTWkJUSS5HT1YuQ06iFzAVoAMCAQKhDjAMGwRIVFRQGwRsb2dzo4IDaDCCA2SgAwIBF6EDAgEMooIDVgSCA1L3mblv51lhhUk65uuHdDfZVu5MH7BU3VM0Ouk3Nz2omVDTFxoSmcRhyvP3YUWS9sJIvQf74ztvLuEnN3Oevcj+p9IfI4YceqfkuYuwm0AUS57PN+OGRXr9TFL4+/A0CakEb8v6Hie4OHCoTHTBc9/XuOIn80BmkOip0/Eh4h6pw60MumZHULxeaAOtEI0ECPk4OULeh2W8MeF3iWEOQyFExKY2A1aRZoUhVIbII1G45OYZz03EC869H8z8hzc4fpW6GnHFtneLUAuDusp7ySwMFY5q/xvGu5qygXH86tI/QAkE5qGYgsYM3JjliI6rKFhxcHyqHo+IwWs82LszP3o7V2E2iQsIUZqQo08gyKBwQubBNRETPPrJtT22X4YoJOWB8jYfa4vXfT77n6rLg/ps+4w9l5tOD4cmfWicid1gTKpdYbOlspcnSqa/UrlfqtjJglC1xyRXvOQUJkmSnIUuJEh+YmDWduCFVq6Zhng7/cKceIUHDrK8f0FNJeIqQ5BzqRK2GIy0NpjPgG/Y1apnYEk9HiDjpIz2olk1U9qui+Zp4zekQFEHZp8arRQD5jrvA0Q2qrjgFL1SXZAy+OhbL64p4LQUnJFCidhnpzh4ng0GZIxeWbdtkYJEEwQ8zVKPVSLgTeCnCZ7qzqPFOrHTElcuDj6M7lrpJI9VyhEIQiX1fO9oAVYGSlS/kjANumKdmFarPx0apVJajQUFWN9Hx0bGtsP8A9jfZJRkek5VVeb6NLRy+QVaaa0gOij/E76R0EdLM8/kk9yts5IeUuBnGLLyzvAIRT8UYhUIpLWIk8qfy1+nvW25YyL810Vawnz+AtMBYFXGkXyXJTfc0G+xpElOdM8eqPaYTtzJLvDiu0yQNPYKdyny2PcHXtqjIU4EyVru1cyjoJzp2B/URvkK3bgBh696tHGL1OfNeaBfpDZlwkP3juNxn7DenP5jiwq9hunPMjoDghoNEGcHC++oLgWdgq7IViUkGuGbHGL96eYN/bPIhFWnEUlNM+lSxEYhWHZB/iRSE53crzJN7n0hobDtSUg5c7l/2BqIVsZkqY+yzh60uLTmOxNfMguAWdu4YdfqE74EDO2cdMaAq99r93CjLWySbhvKtKVCv9C5M+aGpIG6MIG3oAMCAReiga8EgaygGo+fZv6Mbh9qTCUKlJ2aY9RZ9VpOnOy4zPIuw6JNHShr1kNckSS/j+TRrCfQRaoeoQlhOWFkrkqjtl2GCpvBG3ZcTd7rXHeAV5Tc+rd/TADsbya2ZnEx/o5TcTmPe4gauuTFpwL2RTaFzY8oIkGvh0kmOu/M/OvXUiFqHN/ua556UPePQ9qbRM198a1pNXk167QDhZjfT4tsPlkeRf84NfzOayDhcFrLf1g4

Host:logs:81

1.4.服务端验证通过,返回页面

HTTP/1.1200OK

Content-Length:167

Content-Type:text/html

Last-Modified:Wed,14Nov200708:21:24GMT

Accept-Ranges:bytes

ETag:"bf2d54589726c81:e86"

Server:Microsoft-IIS/6.0

X-Powered-By:ASP.NET

WWW-Authenticate:NegotiateoYGgMIGdoAMKAQChCwYJKoZIgvcSAQICooGIBIGFYIGCBgkqhkiG9xIBAgICAG9zMHGgAwIBBaEDAgEPomUwY6ADAgEXolwEWgai3BchBA/s/Vtx44FMiv7n0LcpxmkRlVRhgIhsuijQnu6/qIb0AsMrIU4nHqDlZnLOkVwlXDAIiTumPWfHK+V/DmjKF5O6jlJVdFSu9xghGGyYivc3fvCWSQ==

Date:Fri,23Nov200707:22:32GMT

<html>

<head>

<metaHTTP-EQUIV="Content-Type"Content="text/html;charset=gb2312">

</head>

<bodybgcolor=white>

Thisisasimplepage!

</body>

</html>

2、客户端和服务端机器都在域,客户端以域帐户登录,以服务器名访问以外的所有情况

2.1.第一次HttpWebRequest先以匿名发送http请求

GET/iisstart.htmHTTP/1.1

Host:logs:81

Connection:Keep-Alive

2.2.服务端返回无授权回应

HTTP/1.1401Unauthorized

Content-Length:1327

Content-Type:text/html

Server:Microsoft-IIS/6.0

WWW-Authenticate:Negotiate

WWW-Authenticate:NTLM

X-Powered-By:ASP.NET

Date:Fri,23Nov200707:22:32GMT

2.3.HttpWebRequest选择NTLM验证,请求质询码

HttpWebRequest判断不满足客户端以域账户登录,并且访问的服务器也是在域中,HttpWebRequest即选择NTLM。

GET/iisstart.htmHTTP/1.1

Authorization:NegotiateTlRMTVNTUAABAAAAt4II4gAAAAAAAAAAAAAAAAAAAAAFAs4OAAAADw==

Host:192.168.100.5:81

2.4.服务器返回质询码

HTTP/1.1401Unauthorized

Content-Length:1251

Content-Type:text/html

Server:Microsoft-IIS/6.0

WWW-Authenticate:NegotiateTlRMTVNTUAACAAAACgAKADgAAAA1goniKBDxpIifbe0AAAAAAAAAAHwAfABCAAAABQLODgAAAA9TAFoAQgBUAEkAAgAKAFMAWgBCAFQASQABAAgATABPAEcAUwAEABgAcwB6AGIAdABpAC4AZwBvAHYALgBjAG4AAwAiAGwAbwBnAHMALgBzAHoAYgB0AGkALgBnAG8AdgAuAGMAbgAFABgAcwB6AGIAdABpAC4AZwBvAHYALgBjAG4AAAAAAA==

X-Powered-By:ASP.NET

Date:Fri,23Nov200708:46:23GMT

2.5.HttpWebRequest发送登录本机的账户加密后的质询码

HttpWebRequest通过CredentialCache.DefaultCredentials获得登录本机的用户名和口令,用口令派生的key加密质询码发送到服务器。

GET/iisstart.htmHTTP/1.1

Authorization:NegotiateTlRMTVNTUAADAAAAGAAYAGYAAAAYABgAfgAAAAoACgBIAAAACgAKAFIAAAAKAAoAXAAAABAAEACWAAAANYKI4gUCzg4AAAAPUwBaAEIAVABJAGoAaQBuAGoAegBKAEkATgBKAFoA8Le58UfsaJIAAAAAAAAAAAAAAAAAAAAAsTIQTM1MCkPFXRkaNpjW+aLQCXsOGnUiDBp33pfcOMLLQJQuAyM/zQ==

Host:192.168.100.5:81

2.6.服务器通过验证,返回页面

HTTP/1.1200OK

Content-Length:167

Content-Type:text/html

Last-Modified:Wed,14Nov200708:21:24GMT

Accept-Ranges:bytes

ETag:"bf2d54589726c81:e86"

Server:Microsoft-IIS/6.0

X-Powered-By:ASP.NET

Date:Fri,23Nov200708:46:23GMT

<html>

<head>

<metaHTTP-EQUIV="Content-Type"Content="text/html;charset=gb2312">

</head>

<bodybgcolor=white>

Thisisasimplepage!

</body>

</html>

3、客户端传送定制用户凭据到服务端

前两种情况都是传送客户端当前登录用户的用户凭据到服务端,但有时会需要客户端根据不同的情况以服务端的不同的用户帐号访问服务端资源。

HttpWebRequest.Credentials属性不设置为缺省登录本机的用户CredentialCache.DefaultCredentials,使用NetworkCredential提供定制的用户凭据,这样用法只能使用NTLM验证。

通过NetworkCredential对象定制一个用户凭据,像这样:

myHttpWebRequest.Credentials=newNetworkCredential("用户名","口令");

这里的用户名用户名和口令是服务端的用户,这样设置以后,HttpWebRequest的行为跟上面第二种情况一样,也是先以匿名发送请求,收到服务端返回的无授权(要求windows验证)的http回应后,HttpWebRequest选择NTLM,其后的过程也跟上面第二种情况一样。

三、基本身份验证

服务端IIS设置为不允许匿名访问,只选择了基本身份验证,客户端使用HttpWebRequest发送一个get请求,请求一个页面。

基本身份验证,客户端直接把用户的用户名和密码简单的转换为base64编码后发送到服务端,属于明码传送,不具安全性。

基本身份验证,HttpWebRequest.Credentials属性只能使用NetworkCredential来传送用户名也密码,CredentialCache.DefaultCredentials不支持基本身份验证。

在服务端只要求基本身份验证的情况下,如果HttpWebRequest.Credentials属性使用的是CredentialCache.DefaultCredentials,当收到服务端返回无授权(要求基本身份验证)回应后,HttpWebRequest直接跑出无授权异常。

客户端用户凭据也是这样:

myHttpWebRequest.Credentials=newNetworkCredential("用户名","口令");

但是,根据服务端不同的回应,HttpWebRequest会有不同的动作。

看一下整个请求响应过程:

1.1.第一次HttpWebRequest先以匿名发送http请求

GET/iisstart.htmHTTP/1.1

Host:2003base

Connection:Keep-Alive

1.2.服务端返回无授权回应

服务端IIS设置为不允许匿名访问,要求基本身份验证,所以服务端返回无授权回应,同时在http头加了个WWW-Authenticate:Basicrealm="2003base"头,Basic表示要求基本身份验证。

HTTP/1.1401Unauthorized

Content-Length:1327

Content-Type:text/html

Server:Microsoft-IIS/6.0

WWW-Authenticate:Basicrealm="2003base"

MicrosoftOfficeWebServer:5.0_Pub

X-Powered-By:ASP.NET

Date:Mon,26Nov200708:52:42GMT

1.3.HttpWebRequest发送base64格式的用户名和密码

HttpWebRequest收到Basic的验证头后,就把NetworkCredential提供的用户名和口令链接起来,转换成base64编码,直接发送到服务端。

Base64编码用户名和密码看上去是这样的:Y2hua2luZzpwYXNzd29yZA==

经过转换后,可以看到用户名和密码是:chnking:password

GET/iisstart.htmHTTP/1.1

Authorization:BasicY2hua2luZzpwYXNzd29yZA==

Host:2003base

1.4.服务器通过验证,返回页面

HTTP/1.1200OK

Content-Length:200

Content-Type:text/html

Last-Modified:Fri,23Nov200707:00:18GMT

Accept-Ranges:bytes

ETag:"6084ba819e2dc81:356"

Server:Microsoft-IIS/6.0

MicrosoftOfficeWebServer:5.0_Pub

X-Powered-By:ASP.NET

Date:Mon,26Nov200708:52:42GMT

<html>

<head>

<metaHTTP-EQUIV="Content-Type"Content="text/html;charset=gb2312">

<titleID=titletext>......</title>

</head>

<bodybgcolor=white>

.Thisisasamplepage!

</body>

</html>

四、一个应用程序访问webservices的例子

1.1.Webservices端代码

很简单的一个Webservices,一个foo方法,输入一个整数,返回一个这个整数乘以十后的字符串,内容如下:

[WebService(Namespace="http://chnking.com/")]

[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]

publicclassFOOSAMPLEService:System.Web.Services.WebService

{

[WebMethod]

publicstringfoo(inta)

{

return(a*10).ToString();

}

}

1.2.Soap调用webservices的格式

发布为webservices后,在浏览器浏览这个webservices的asmx文件,可以看到这个foo如何用soap协议进行调用。

以下是SOAP1.2请求和响应示例。所显示的占位符需替换为实际值。

POST/WS1/Service.asmxHTTP/1.1
Host:localhost
Content-Type:application/soap+xml;charset=utf-8
Content-Length:length
<?xmlversion="1.0"encoding="utf-8"?>
<soap12:Envelopexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<fooxmlns="http://chnking.com/">
<a>int</a>
</foo>
</soap12:Body>
</soap12:Envelope>


HTTP/1.1200OK
Content-Type:application/soap+xml;charset=utf-8
Content-Length:length
<?xmlversion="1.0"encoding="utf-8"?>
<soap12:Envelopexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<fooResponsexmlns="http://chnking.com/">
<fooResult>string</fooResult>
</fooResponse>
</soap12:Body>
</soap12:Envelope>


1.3.客户端应用调用webservices代码

下面代码在应用程序中用HttpWebRequest对象以上面webservices要求的格式发送soap请求。服务端设置为只允许windows身份验证,HttpWebRequest对象同时传送用户凭据,最后接收服务端的返回的soap的结果。

//根据需要访问的URL新建HttpWebRequest对象

HttpWebRequestmyHttpWebRequest=(HttpWebRequest)HttpWebRequest.Create("http://localhost:81/ws1/Service.asmx");

//要发送soap请求的内容,必须使用post方法传送数据

myHttpWebRequest.Method="POST";

//缺省当前登录用户的身份凭据

myHttpWebRequest.Credentials=CredentialCache.DefaultCredentials;

//准备soap请求的内容

stringcont;

cont="<?xmlversion='1.0'encoding='utf-8'?>";

cont+="<soap12:Envelopexmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xmlns:xsd='http://www.w3.org/2001/XMLSchema'xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>";

cont+="<soap12:Body>";

cont+="<fooxmlns='http://chnking.com/'>";

cont+="<a>1</a>";

cont+="</foo>";

cont+="</soap12:Body>";

cont+="</soap12:Envelope>";

byte[]byteRequest=Encoding.UTF8.GetBytes(cont);

myHttpWebRequest.ContentType="application/soap+xml;charset=utf-8";

myHttpWebRequest.ContentLength=byteRequest.Length;

myHttpWebRequest.Timeout=100000;

//将soap请求的内容放入HttpWebRequest对象post方法的请求数据部分

StreamnewStream=myHttpWebRequest.GetRequestStream();

newStream.Write(byteRequest,0,byteRequest.Length);

//发送请求

HttpWebResponsemyWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse();

//将收到的回应从Stream转换成string

newStream=myWebResponse.GetResponseStream();

byte[]byteResponse=newbyte[myWebResponse.ContentLength];

newStream.Read(byteResponse,0,(int)myWebResponse.ContentLength);

//str里面就是返回soap回应的字符串了

stringstr=Encoding.UTF8.GetString(byteResponse);

myWebResponse.Close();

返回的str的结果是:

<?xmlversion="1.0"encoding="utf-8"?><soap:Envelopexmlns:soap="http://www.w3.org/2003/05/soap-envelope"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><fooResponsexmlns="http://chnking.com/"><fooResult>10</fooResult></fooResponse></soap:Body></soap:Envelope>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: