ASP.NET MVC和WebAPI已是.NET Web部分的主流,刚开始时两个公用同一个管道,以后为了更加的轻量化(WebAPI是对WCF Restful的轻量化),WebAPI使用了新的管道,所以二者相关类的命名空间有细微差别,在使用时须要注意。javascript
WebAPI学习系列目录以下,欢迎您的阅读!html
快速入门系列--WebAPI--04在老版本MVC4下的调整算法
ASP.NET MVC的路由:Routes(RouteCollection)的线程安全,读写锁,GetReadLock, GetWriteLock。RouteTable.Routes.MapPageRoute(…);编程
命名空间为System.Web.Routing中json
WebAPI的路由:首先介绍其相关类型,他们均是对Http报文的简易封装,System.Net.Http(HttpRequestMessage, HttpResponseMessage)。windows
命名空间为System.Web.Http.Routing中api
HttpRouteHandler。
还记的ASP.NET MVC中的核心是HttpHandler,而在WebAPI中其管道处理器是HttpMessageHandler。在实际中其经过职责链模式将委托经过InnerHandler(DelegationHandler)方式进行处理。其中,其中这个管道最开始的是httpServer,最末端的是HttpRoutingDispatcher(均在System.Web.Http命名空间下,支持异步模型),P108
Tip:额外想一想也能理解WebAPI管道为何更加轻量化,于是它只须要处理Json等类型数据,不须要考虑如页面、JS、静态资源等内容。
Class: [RoutePrefix("api/demo")],针对具体类的路由设置,相对RouteConfig,粒度更细。
Method: [Route("action")]
[HttpGet], [HttpPost]
关于Web服务,其中比较难的概念通常都集中在安全,其相关概念很是的多,包括Windows相关认证模式、Forms认证、第三方认证、跨域访问等,接下来一一介绍。此外还会附加HttpClient、IOC框架的选择、服务幂等性、SignalR、EntLib中的EHAB等概念。
.NET安全模型:
Identiy表示用户身份, Identity AuthenticationType, IsAuthenticated, Name},常见的Identity有WindowsIdentity, FormsIdentity, GenericIdentity。P556
IPrincipal, 被成功实施受权的实体,等价于身份加角色,包括WindowsPrincipal(windows的权限组),GenericPrincipal, RolePrincipal(Membership组件和Roles组件) 。常见的认证方式经过"质询-应答"(challenge-Response)方式。
常见http认证方式,Basic和Digest,前者使用将认证凭证(用户名+密码)经过base64编码而未加密,但咱们可使用https传输来解决机密性问题。与此相关的两个过滤器, AuthenticationFilter和AuthorizationFilter。
补充ActionFilter概念,好比请求涉及大量运算,而且输入和输出一一对应(即相同的输入有相同的输出),那么能够考虑缓存Action。P585
Windows认证模式(均经过在IIS中设置身份认证模式)
WebHost寄宿下的安全:Windows认证模式,经过Basic, Digest认证方案,最终采用NTLM或者Kerberos协议。认证用户的Principal体如今HttpContext、当前线程、ApiControlelr。Keep-Alive,Fidder查看调用。
名称 | 状态 | 响应类型 |
Active Directory客户端证书身份验证 | 已禁用 | HTTP 401 质询 |
ASP.NET 模式 | 已禁用 | |
Forms身份验证 | 已禁用 | HTTP 302 登陆/重定向 |
Windows身份验证 | 已禁用 | HTTP 401 质询 |
基自己份验证(Windows/Basic) | 已禁用 | HTTP 401 质询 |
匿名身份验证 | 已禁用 | |
摘要式身份验证(Windows/digest) | 已启用 | HTTP 401 质询 |
如今都是HTTP401 质询模型,只有forms是http 302 登陆/重定向。这个关于basic的质询方式颇有意思,就是当你请求时,出现http 401,会要求你输入用户名密码,输入后你输入的用户名和密码会被base64编码发送的服务器,形式是Basic YWRtaW46YWRtaW4=,这部分的head就是authentication。查看windows的凭据管理器,帐号密码木有问题,但仍然不能经过验证,很是的伤感,本身试着加上域cn1\,结果OK了,感受棒棒哒,哈哈,说明asp.net安全模型和windows有很好的整合性。
Basic模式的流程是,浏览器向服务器IIS以匿名的方式发送GET请求,IIS回复一个401 Unauthorized的响应,该响应用"www-authenticate"报头告诉客户端采用的认证方案(basic)和对应的领域(Realm, localhost)。浏览器收到响应弹出登陆对话框,收集输入的帐号密码组成字符串做为认证凭证,接下来,浏览器再次发送请求,在authorization包头中携带认证的方案和用户的凭证Basic YWRtaW46YWRtaW4=,IIS解密后认证,action顺利执行。
Base64:是网络常见的用于传输8bit字节代码的编码方式,用在http表单(包括隐藏的表单域)和http GET url中,base64编码的信息具备不可读性,但不具备机密性,使用时须要注意应用场景。
Digest认证仅仅适用于Domain模式,若是基于WorkGroup模式,也没法使用,接下来经过fiddler看看相应的HTTP消息头。
HTTP 401的响应:
WWW-Authenticate: Digest qop="auth",algorithm=MD5-sess,nonce="+Upgraded+v1e4fcae181b935afc3d94f30f5033141a25e3c7e4b83bd101c60cf10ea425a352c8959c8d47e643e5fc38f90cffe411be5f7a99033900ae4d",charset=utf-8,realm="Digest"
Digest认证传输用户凭证的哈希码,而不是明文。客户端首先匿名向服务器发送GET请求,服务器返回一个401响应,这个响应包含一个"WWW-Authenticate"报头,携带的信息包括。
参数 | 解释 |
Digest | 认证方案 |
Realm="Digest" | 领域 |
Algorithm | 表示服务端支持的哈希算法,MD5-sess |
Nonce | 服务端生成的惟一性标示,通常来讲,IIS会利用当前时间戳以及请求的Etag(被请求变量的实体值)报头值来生成这个nonce |
Qop(Quanlity of Protection) | IIS采用qop通知客户端采用的消息保护等级,可选值包括auth(authentication), auth-int(authentication-integrity),前者仅限于基本的认证,后者还确保传输内容的一致性。 |
输入帐号密码的再一次请求(响应为200成功):
Authorization: Digest username="cn1\\she_s", realm="Digest", nonce="+Upgraded+v1e4fcae181b935afc3d94f30f5033141a25e3c7e4b83bd101c60cf10ea425a352c8959c8d47e643e5fc38f90cffe411be5f7a99033900ae4d", uri="/Sory.Entertainment.WebAPI/", algorithm=MD5-sess, response="9a6cb99fad4404cdd521e5db432f6b09", qop="auth", nc=00000001, cnonce="c77c05d93544b363"
其相关参数为:
参数 | 解释 |
Username | 表明客户端的用户名,看来用户名仍是能够截取的 |
Qop | 最终采用的消息保护等级, qop="auth" |
Algorithm | 最终采用的加密算法,MD5-sess |
Nonce | 实际就是服务器端生成的nonce |
cnonce | 客户端生成的nonce(c表明client),它能够对请求内容签名以确保内容未被篡改,能够帮助客户端对服务端实施认证(服务端可以证实知道该nonce,这些很适合防护跨站请求伪造的防护) |
Nc(nonce count) | 它表示客户端针对同一个nonce发送请求的数量,一位着这是随着请求不断增长的数字,IIS能够经过nc表明的数字来防止"重放攻击",它会维护每一个nonce的nc,若是请求携带的nc比这个少,会被认为是不合法的请求。 |
IIS在接受到第二次请求后,它先对请求进行合法性校验(好比nc的合法性),而后从Authentication报头提取用户名、nonce和加密算法计算出针对用户名真正的Digest,最终利用它与请求中提供的Digest进行比较确认密码的正确性,完成客户端认证。
Tip:
<script type="application/json" id="__browserLink_initializationData">
{"appName":"Firefox","requestId":"ee1fc1d3f30e4b4cba937703bee3ce10"}
</script>
<script type="text/javascript" src="http://localhost:13820/69ea419b05a141aaa5111affa4bb02fe/browserLink" async="async"></script>
这部分如何理解,与jsonP相关?
不管问basic仍是Digest认证,若是使用浏览器作客户端,第一次访问总须要在弹出框中输入,很是繁琐,而且密码在网络中传输,有安全风险,通常采用加盐的方式避免。集成Windows认证能够很好解决该问题,它默认以登陆机器的Windows帐号的名义来访问被受权的资源没,用户的密码被包含在请求携带的安全令牌中,很是的方便,该方式最终使用NTLM和Kerberos协议来完成。
NTLM协议(比较陈旧):采用质询/应答(Challenge/Response)消息交换模式,DC域控制器保存所用用户的相关信息。基本流程为:步骤1,用户输入帐户密码登陆主机,主机会缓存输入密码的哈希值,原始密码会丢失。若是视图访问服务器资源,须要向对方发送请求,请求中包含一个明文表示的用户名;步骤2,服务端接受请求,生成16位随机数(称为质询challenge),存储起来后以明文的形式发送给客户端;和Digest请求中nonce的意图彻底一致;步骤3,客户端收到服务端的质询后,用在步骤1中保存的密码哈希值对其加密,而后将加密后的质询发送给服务端;步骤4,服务端收到加密质询后,会向DC发送针对客户端的验证请求(请求中包括,用户名、客户端密码加密后的质询和原始的质询);步骤五、6,DC根据用户名得到密码哈希值,对原始质询加密,再与服务端发送的质询比较,一致就为验证经过,不然失败。
Kerberos:这东西也算是困扰了小弟不少年,老看到,尤为每次注册windows时,呵呵,你懂得。实际上它是一种更搞笑安全的认证协议,过程更加的复杂,与NTLM类似,也包含三部分,客户端、服务器和KDC(Key Distribution Center,在windows域中,KDC有DC担当)。Kerberos实际是一种基于票据(Ticket)的认证方式,客户端要访问服务端的资源,首先要购买服务端承认的票据。也就是说,客户端在访问服务器前要先买好票,等待服务器验票后才能入场,但这票不能直接购买,首先须要认购权证(和粮票,股票认购权证类似)。这个认购权证和进入服务器的入场券均由KDC发售,感受各类绕……相关详细内容暂时放一放。
在IIS中使用windows集成验证时,会看到provider的设置,有"negotiate"和"NTLM"两个选项,默认使用前者,其Provider包括"Negotiate: Kerberos",固然也能够自定义。此外,客户端须要在IE设置-》高级中,开启Windows集成认证,默认是开启的。在使用HttpClient时,可使用如下方式,简化调用。
可与独立于windows系统的认证方式,之前作webform时,forms认证是用的最多的,当时还一直觉得forms验证也须要和windows相关,尤为是和webForm中的form相关,如今想一想挺幼稚的,同时这个验证能够和membership很好的搭配在一块儿。但实际上这种验证方式是独立的,适合自行维护用户帐号和密码的场景,也是绝大部分项目的场景。那么接下来介绍forms认证是如何进行的,努力使本身真正的走出误区。
Forms认证的流程设计4次的消息交换,其具体步骤以下所示。
步骤1:用户经过浏览器匿名向IIS发起请求,假设地址为"/home",它会收到状态为"302, Found"的相应,这是一个用于实现"重定向"的http响应,它经过location报头表示的重定向地址指向登陆的页面,以前访问的地址将做为查询字符串returnURL的值。
步骤2:浏览器接受到该请求后,针对重定向的地址发送请求,登陆页面最终被呈如今浏览器。
步骤3:用户输入正确的用户名密码后提交表单,服务器在接受到请求以后提取它们对用户实施认证,认证成功后,它会生成一个安全令牌或者认证票据。接下来,经过查询字符串returnURL表示的原始请求地址,做为另外一个状态为"302, Found"响应的Location报头,而通过加密/签名的安全令牌做为该响应的Cookie。
步骤4:这个表明安全令牌的Cookie将自动附加到浏览器后续的请求中,服务器直接利用它对请求实施认证。Cookie的名称、过时策略以及采用的保护等级都可以经过配置来控制。在禁用Cookie的状况下,安全令牌会直接做为URL的一部分传送。
Tip:
首先想补充补充的是原来的forms认证的配置经过以下配置,加上在login相关方法上加上[AllowAnonymous],而后IIS中设置启用匿名认证和forms认证便可。
在ASP.NET 5以后的版本配置方式有一些变化,为了和第三方认证OAuth集成,不须要配置文件的配置,而是经过以下代码配置,若是添加每每会出错。
Cookie采用的保护等级,在IE设置中包括6个隐私等级,对cookie的管理程度各不相同,从cookie彻底不可读写,到彻底可读写,默认的等级为中,阻止没有精简隐私策略的第三方cookie。
昨天和同事聊天时,还注意到有的项目的logoff是直接跳转页面,而不是action,所以缺乏清空session等服务器端信息的操做,在实际开发中也算是个易错点。
以前介绍的认证方式,都要求密码(token)在网络中进行传输,为了确保密码不被窃取,须要用SSL\TLS对传输的内容实施保护。其中涉及不少安全相关的基础知识点,这儿只作简要介绍。
Tip:对于数字证书想说的是,必定要把它才分开了理解,大致包含三部分,公钥信息、签名信息和其余信息。而且后面二者都是为前者的安全送达服务的,简而言之(如12306购买火车票场景,祝愿你们都能买到过个幸福年,哈哈),网站经过要求用户安装根证书的方式将网站通讯密钥对中的公钥发送给我,但为了保证这个过程的安全,就须要提供数字签名的过程。就像将情报通信密码给我,而且签上了FBI同样,以后就能够用这个密码进行通信了。这个说的比较粗略,有些简化,省略了认证权威机构和认证树的概念。
关于SSL/TLS的概念,后者TLS(Transport Layer Security)实际上是前者SSL(Secure Sockets Layer)的升级版本,TLS1.0就是SSL3.1,在IE的设置中,能够看到默认支持SSL 3.0和TLS1.0。而HTTPS是指HTTP与SSL/TLS的结合,像以前介绍的12306的安全,就是https的,也称为弱安全模型,那么强安全模型是什么?那就是咱们使用网银时,你们都经历安装安全控件甚至使用U盾的过程,这儿就是强安全。简单来讲,强安全,指服务器端和客户端都要安装对方的证书,相互认证;弱安全,指客户端安装服务器证书,客户端认证服务器。接下来介绍请求Https网站的过程。
步骤1:客户端向https站点发送协商请求,包括客户端所支持的加密算法列表
步骤2:Https站点从算法列表中选择所能支持最合适安全级别的算法(安全性和效率折衷),连同绑定到该站点的数字证书一并发送给客户端。
步骤3:客户端接受证书后,经过验证确认站点身份,成功后,生成一个随机数,做为会话密钥(Session key)缓存在客户端。客户端采用发回的加密算法,利用证书中的公钥对该密钥(Session Key)加密,加密后发送给站点,站点解密得到Session key。
步骤4:客户端和服务端使用该Session key使用对称加密算法进行加解密。(对称加密效率高,但密钥管理难,所以采用结合二者的方式,用非对称加密管理密钥,用密钥来对称加密,棒棒哒)
IIS对多种传输协议提供支持,包括http、Tcph和MSMQ等,站点绑定数字证书的方式哟不少,最方便的是用iis管理器,其步骤以下。
步骤1:在未目标站点添加https绑定以前,咱们须要为它准备一张证书,能够用makeCert.exe工具,也可使用iis管理器来建立自我签名的证书。在IIS的特性列表中选择"服务器证书",以后选择"建立自我签名证书",命名和站点名称相同便可。
步骤2:在IIS中,选择咱们指定的站点(Web Site),右键选择编辑绑定,在网站绑定页面添加https类型并选择相应的证书,在浏览网站栏就能够看到http, 和https了。这时你就能够浏览网页经过两种不一样的方式,固然你自定义的证书未被加入根证书,所以用https时,浏览器会显示一个小红叉。以后在httpclient部分,你也会发现,咱们能够经过设置,跳过客户端对服务器证书的验证,方便调用,不过不推荐。
网站的常见调用能够经过http和https两种方式,但具体到某一个调用的时候,须要在"安全"和"性能"间权衡,可是认证过程必须采用https,将指定的action设置为[RequireHttps],那么它就只能经过https协议访问到。该特性实际是MVC提供的一个AuthenticationFilter,若是是一个普通请求,则会把该请求重定向到https的相应地址。这儿你们会注意到一个问题就是requiredHttps是MVC下的概念,那么WebAPI中有对应概念么?这个能够经过自定义的认证过滤器来处理。
通常来讲,web应用的用户认证均由自身完成,经过存储用户名和密码并进行验证,但这种方式在当前的互联网场景下会有一下两个主要问题:用户须要注册不一样的帐号,记住和使用很是的麻烦了;对于应用提供者,大量认证系统会花费大量的精力。基于OAuth2.0(Open Authentication 2.0)的第三方认证模型的出现正好能够解决这个痛点,该模型借助了Google, 微信等值得信赖的IT服务提供商。OAuth是定义一种协议帮助资源的拥有者在不提供自身凭证的前提下受权第三方应用以他的名义存储保护的资源。
得到资源拥有者受权的第三方应用获取受保护的资源采用的不是受权者凭证,而是一个被称为Access Token的安全令牌,Access Token颁发过程会涉及若干不一样的角色。接下来经过一个蒋大师提到的简单例子作相应的介绍。例如咱们开发了一个集成了新浪微博认证用于发布打折商品信息的App,通过用户受权以后它能够调用新浪微博的WebAPI获取用户的电子邮箱地址并发布相应的打折消息。那么OAuth在该场景下的做用是,用户受权该应用以本身名义调用新浪微博的webAPI获取本身的邮箱地址,涉及4个角色:资源拥有者,通常为最终用户;客户端应用,须要得到资源拥有者受权并最终访问受保护资源的应用;资源服务器,最终承载资源的服务器,一本为一个webAPI;受权服务器,它对用户和客户端实施认证,并在用户受权的状况下向客户端应用颁发Access Token,在以前介绍的场景下,二者合一,均为新浪微博。
通常来讲,若是须要针对某个第三方认证服务来开发应用,须要向对应的认证服务提供商对应用进行注册,成功后得到AppID/AppSecet(名称不必定同样),实际工做中其实每一个项目每每也有AppID。常见的,咱们能够申请windows服务https://account.live.com/developers/applications/, 申请应用后能够获取clientID和clientSecret,而且设置重定向的域名。这儿想提醒你们的一点,就是这个重定向设置能够是多个,而且必定要和你每个请求的重定向设置对应起来,一旦没有设置,windows live会报没法提供服务的错误。
这儿流程相似于Kerberos认证,首先客户端获取受权凭证,以后再购买访问凭证,最后访问资源。Authorization grant(缩写AG)包含4中类型:Implicit,省略了获取AG过程;Authorization Code, 标准模式,这个AG是一个受权码;以后的两种不太有价值,就不介绍了。
该模型中,经过获取当前请求的AccessToken,以后调用Windows Live Connect提供的API(https://apis.live.net/v5.0/me)。不过在此以前,若是用户未登录到Windows Live,那么首先会跳转到登录页面,完成GetProfile调用后将json格式字符串显示在浏览器中。这儿的核心是,咱们经过AuthenticateAttribute将AccessToken写入Cookie中,这与Forms认证类似,不过从安全角度讲,利用Cookie携带安全令牌会引发被称为"跨站请求伪造CSRF, Cross-Site Request Forgery"的安全问题,因此用htto报头来做为安全令牌的载体比较合理。在IAuthenticationFilter接口的ChallengeAsync用于在认证过程当中向客户端发送"质询"响应,若是AccessToken不存在,就像WindowLive受权页面重定向,参数(response-type, redirect_uri, client, scope)以查询字符串形式提供。而IActionFilter中的方法ExecuteActionFilterAsync用于将AccessToken写入cookie。代码以下所示:
Tip:
location是javascript里边管理地址栏的内置对象,好比location.href就管理页面的url,用location.href=url就能够直接将页面重定向url。而location.hash则能够用来获取或设置页面的标签值。好比http://domain/#admin的location.hash="#admin"。利用这个属性值能够作一个很是有意义的事情。简单来讲就是"#"号后面跟着的内容,相似于查询字符串。
window.location.hash这个属性可读可写。读取时,能够用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。
以前介绍的IMP存在两个问题,其一,受权服务器没有对客户端应用进行认证,由于获取Access Token的请求只提供了客户端应用的ClientID而没有ClientSecret;其二,Access Token是受权服务器单独颁发给客户端应用的,应该对于其余人是不可见(包括拥有被访问资源的受权者)。IMP类型受权的客户端运行于纯客户端上下文环境,AC类型的使用户运行于服务器的应用,好比MVC应用中的Controller。
步骤1:客户端向受权服务器发送一个获取Authentication Code(认购权证)的请求,请求的地址和参数和IMP类似。
参数名 | 解释 |
Response_type | 表示请求但愿获取的对象类型,在此咱们但愿获取的是Authorization Code |
Redirect_uri | 表示受权服务器在得到用户受权并完成对用户认证后重定向的地址,AC就是以查询字符串方式附加 |
Client_id | 受权客户端应用的clint_id |
Scope | 表示受权的范围,根据具体须要的权限集而定 |
步骤2:客户端利用AC向受权服务器获取Access Token,通常为POST请求,参数包括:
参数名 | 解释 |
Client | 受权客户端应用的clint_id |
Client_secret | 该标识对应的ClientSecret |
Redirect_uri | 以前获取AC时指定的重定向地址 |
Grant_type | 采用Authorization Grant类型,值为"authorization_code" |
受权服务器接受到请求后,除了利用clientID和Secret对客户端实施验证外,还会检查重定向地址是否一致,完成后,生成一个AccessToken发还。消息包括:token_type,bearer;expires_in,3600;scope,wl.signin wl.basic;access_token;authentication_token。
出于安全考虑,access token有一个过时时限,此外受权服务器还会返回一个长期有效的安全令牌,当ac token过时时,能够利用它再获取,使用它须要在scope中加入"wl.offline_access",相关代码以下所示。
对了,实际使用中,不须要这么麻烦,你能够看到在project的app_start的StartupAuth中,能够看到微软的设置,只用输入对应的clientId和clientSecret。
Tip:
一个问题,为何我设置的www.sory.com能够访问到,而我并未申请该域名和绑定IP?
WebAPI采用REST风格,将浏览器做为执行上下文客户端js应用是主要消费者,但"同源策略"限制了js的跨站点调用,这将致使WebAPI不能跨域访问资源,那么它将"名存实亡",如何解决这个问题呢?将在后面意义道来,主要有jsonP和cros规范两种方式。
浏览器做为internet工具,它为客户端应用提供一个寄宿和运行的环境。这个应用就是javaScript程序,因为js脚本并不是都值得信奈,因此对js运行限制在一个沙盒sandbox中。同源策略是一项最基本的安全策略,是浏览器安全的基础,它限制了来自A站点的脚本只能操做A的页面的DOM,跨域操做B站点的资源将会被拒绝。同源要求一下3方面相同:主机名称(域名/子域名或者IP地址);端口号;网络协议(Schema)。须要注意的,对于一段js脚原本说,其"源"与它存储的地址无关,而取决于脚本被加载的页面,JSONP就利用了这个特性。除了<script>标签,html还有其余一些具备src属性的标签(<img><iframe><link>)均具备跨域加载资源的能力,对于这些标签,每次加载都涉及一个GET请求。同源策略主要针对Ajax请求,该策略主要限制了经过XMLHttpRequest发送的Ajax请求,若是是一个异源地址,浏览器将拒绝读取返回的内容。
一个跨域访问的小例子,一个MVC的应用去调用一个webAPI应用的服务,二者在不一样的接口下时。
跨域调用的错误信息:XMLHttpRequest cannot load http://www.sory.com/Sory.Entertainment.WebAPI/api/contact. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:26829' is therefore not allowed access.
以前说过,js脚本的源有加载页面决定,而不是存储地址。对于一段<script>标签src属性加在的js脚本,它与当前页面同源。对于以前的例子来讲,能够将联系人列表的呈现单独定义在listContacts函数中,并将WebAPI的地址置于<script>标签的src属性中来间接调用。
命名空间:System.Net.Http,简化了咱们原有的HttpWebRequest的调用模式。
基本使用:
HttpResponseMessage response = client.GetAsync("http://...").Result;
Cw(response.Content.ReadAsAsync<DateTime>().Result.ToString();(这儿的result与await很相似啊, Task<long>)
这儿须要注意,首先在nuget中获取httpClient相关组件,其依赖于Microsoft.Bcl库,部分扩展方法须要添加相应命名空间,本身找了半天ReadAsync<T>这个泛型方法半天没找到,也能够本身写一个,比较简单方便。
在Froms认证时,咱们首先须要请求login页面,将用户名密码做为token发送给服务器,以后获取服务器响应信息head中的"Set-Cookie"属性,接着获取其中key为".ASPXAUTH"的cookie信息,这个也就是服务器端和客户端通讯的token。以后再在本身真正须要的请求中,附加上该token(用FormUrlEncodeContent打包,这个类实际气的就是原来mediaType="application/x-www-form-urlencoded"的做用),还有要注意的是httpClientHandler中须要初始化CookieContainer。
参考资料: