有个项目需要调用第三方SDK,而SDK获取服务器的已安装的特殊打印机列表返回给调用方。

但我不想依赖这个SDK,因为这个SDK是使用.NET Framework编写的,而我的项目是使用.NET Core编写的,并且想要部署在Docker容器内运行。

于是反编译了SDK,查看源代码,看到该SDK调用了一个URL获取结果。

而这个URL是本地URL,http://localhost开头的,此时我才知道这个SDK所对应的软件在服务器提供了一个本地的Web服务。

于是我在项目里移除这个SDK,直接调用URL。

但获取结果失败了,提示“响应状态代码不指示成功: 401 (Unauthorized)。”。而直接浏览器访问这个URL却成功返回结果。

刚开始一脸懵逼,不知道原来是没有认证的原因在作梗...

很习惯性的就祭出Fiddler监听这个URL,在浏览器里直接访问这个URL,在Fiddler却看到这个URL被请求了3次。

当时没有在意,直接拿到Request Header,塞到HttpClient的Header里,再次请求,还是报错。

重新粗略地看Fiddler,这时才留意到重复请求3次的问题。

我以为是请求内重定向,设置AllowAutoRedirect为true,再次请求,又报错。

又重新仔细地逐条看Fiddler,第二条在Request Header出现了Authorization: Negotiate xxxxxxxxx。

这才知道用了Authorization认证,于是我根据URL端口查到Windows的端口占用列表,顺便找到了该端口占用所对应的PID。

找到PID就找到了进程,从而找到进程所在的文件夹目录,查看它的config配置文件,从配置描述来看,这个Web服务更准确来讲是一个WCF服务。

它使用了security节点:

<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"></transport>
</security>

我设置UseDefaultCredentials为true,再次请求,成功获取结果。

这是HttpClient请求本地WCF服务 最终代码:

private static async void Test()
{
Random rand = new Random();
var r = rand.Next(, );
string url = "http://localhost:8080/WebPrintService/GetClientPrinters?rand=" + r; var handler = new HttpClientHandler();
//handler.AllowAutoRedirect = true;
//handler.UseDefaultCredentials = true;
//handler.PreAuthenticate = true; HttpClient httpClient = new HttpClient(handler); //HttpRequestMessage requestMessage = new HttpRequestMessage();
//requestMessage.RequestUri = new Uri(url);
//requestMessage.Method = HttpMethod.Get; //requestMessage.Headers.CacheControl.MaxAge = TimeSpan.Zero;
//requestMessage.Headers.Authorization=new AuthenticationHeaderValue(); //requestMessage.Headers.Accept.Clear();
//requestMessage.Headers.Accept.ParseAdd("application/json, text/javascript, */*; q=0.01"); //requestMessage.Headers.AcceptEncoding.Clear();
//requestMessage.Headers.AcceptEncoding.ParseAdd("gzip, deflate"); //requestMessage.Headers.AcceptLanguage.Clear();
//requestMessage.Headers.AcceptLanguage.ParseAdd("zh-CN"); //requestMessage.Headers.UserAgent.Clear();
//requestMessage.Headers.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"); //requestMessage.Headers.Add("X-Requested-With", "XMLHttpRequest"); //var responseMessage = await httpClient.SendAsync(requestMessage);
//var result = await responseMessage.Content.ReadAsStringAsync(); var result = await httpClient.GetStringAsync(url);
JsonConvert.DeserializeObject<PrinterInfo>(jsonString); //第二种写法,.NET Framework自带,无须为了HttpClient使用NuGet引入Microsoft.Net.Http包
//WebRequest request = WebRequest.Create(url);
//request.Method = "GET";
//request.UseDefaultCredentials = true;
//WebResponse response = request.GetResponse();
//var stream = response.GetResponseStream();
//using (var streamReader = new StreamReader(stream))
//{
// using (var textReader = new JsonTextReader(streamReader))
// {
// var serializer = new JsonSerializer();
// var result = serializer.Deserialize<List<PrinterInfo>>(textReader);
// }
//}
}

一个HttpClient使用Windows认证请求WCF服务的例子的更多相关文章

  1. Ajax请求WCF服务以及跨域的问题解决

    Ajax请求WCF服务以及跨域的问题解决 这两天准备重构一下项目,准备用纯html+js做前台,然后通过ajax+WCF的方式来传递数据,所以就先研究了一下ajax访问的wcf的问题,还想到还折腾了一 ...

  2. 实现在GET请求下调用WCF服务时传递对象(复合类型)参数

    WCF实现RESETFUL架构很容易,说白了,就是使WCF能够响应HTTP请求并返回所需的资源,如果有人不知道如何实现WCF支持HTTP请求的,可参见我之前的文章<实现jquery.ajax及原 ...

  3. WCF服务寄宿IIS与Windows服务 - C#/.NET

    WCF是Windows平台下程序间通讯的应用程序框架.整合和 .net Remoting,WebService,Socket的机制,是用来开发windows平台上分布式开发的最佳选择.wcf程序的运行 ...

  4. WCF服务寄宿IIS与Windows服务

      WCF是Windows平台下程序间通讯的应用程序框架.整合和 .net Remoting,WebService,Socket的机制,是用来开发windows平台上分布式开发的最佳选择.wcf程序的 ...

  5. 使用Impersonation仿冒用户运行WCF 服务方法

    默认情况下,当我们把wcf服务器部署在IIS上时, 我们访问wcf时使用的是IIS内建的内建角色,对于IIS8.0,它被命名为ApplicationPoolIdentity, 一般来说,系统为每个应用 ...

  6. 使用IIS发布WCF服务

    上一篇是Windows服务为宿主的WCF服务,现在用IIS为宿主发布WCF服务. 第一步:肯定是新建一个WCF服务啦[是WCF服务应用程序],然后在解决方案上再次添加一个新项目[我们选择WCF服务库, ...

  7. WCF初探-8:WCF服务承载 (上)

    前言 任何一个程序的运行都需要依赖一个确定的进程中,WCF服务也不例外.如果使用WCF服务,我们就必须将服务承载于创建它并控制它的上下文和生存期的运行时环境中,承载服务环境的程序,我们称之为宿主.WC ...

  8. 使用HttpClient消费ASP.NET Web API服务

    本篇体验使用HttpClient消费ASP.NET Web API服务,例子比较简单. 依次点击"文件","新建","项目". 选择&quo ...

  9. Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7932268 在前面一篇文章中,我们分析了And ...

随机推荐

  1. HttpServletResponse实现文件下载

    import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import ...

  2. java 位移运算符

    import org.junit.Test; /** * 1)<< : 左移运算符 * 2)>> : 右移运算符 (测试正数) * 3)>> : 右移运算符 (测试 ...

  3. http://www.rehack.cn/techshare/webbe/php/3391.html

    首先配置好本地PHPstudy环境: 默认在D:\phpStudy\php\php-7.0.12-nts\ext目录下有php_pdo_sqlsrv_7_nts_x86.dll.php_sqlsrv_ ...

  4. chrome 浏览器之下载管理器插件

    chrome默认下载器实在是不招人待见,下面插件是一个非常不错的选择: 名称:Chrono下载管理器 插件地址:https://chrome.google.com/webstore/detail/ch ...

  5. laravel5.4将excel表格中的信息导入到数据库中

    本功能是借助 Maatwebsite\Excel 这个扩展包完成的,此扩展包的安装过程请参考上篇博文:http://www.cnblogs.com/zhuchenglin/p/7122946.html ...

  6. Node.js的进程管理

    众所周知Node基于V8,而在V8中JavaScript是单线程运行的,这里的单线程不是指Node启动的时候就只有一个线程,而是说运行JavaScript代码是在单线程上,Node还有其他线程,比如进 ...

  7. Linux 下安装mysql 5.7

    Linux 下安装mysql 5.7 本人首次安装时按照菜鸟教程的步骤一步一步来的,结果意外的是 装成5.6了,而且各种无厘头的问题,例如无法启动... 本文参照 大佬:‘这个名字想了很久~’ 的&l ...

  8. python学习之旅(三)

    Python基础知识(2):运算符 一.算术运算符 加 +,减 -,乘 *,除 /,幂 **,求余 %,取整 // 二.成员运算符 in,not in 判断一个字符是否在字符串中 name = &qu ...

  9. 关于maven的CoreException: Could not get the value for parameter compilerId for plugin 。。的错误

    在Eclipse中使用 Alt+F5 快捷键,在弹出的Update Maven Project对话框中选择报错的Maven工程,勾选下图中的 Force Update of Snapshots/Rel ...

  10. python----运行机制

    Python 是一门解释型的编程语言,因此它具有解释型语言的运行机制. 计算机程序,其实就是一组计算机指令集,能真正驱动机器运行的是机器指令,但让普通开发者直接编写机器指令是不现实的,因此就出现了计算 ...