有个项目需要调用第三方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. Oracle导出数据EXP00106错误

    在导出dmp文件的时候(命令:exp 用户名/密码@IP/实例名  file=D:\20180910.dmp log=D:\20180910.log),遇到以下错误: 错误原因: 导出使用的是Orac ...

  2. MakeFile 详解

    最近在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了以下这篇文章.通俗易懂.然后把它贴出 ...

  3. 使用stylus

    1. 首先确保  node + npm  环境一切正常. 2. 全局安装  stylus: 在命令行中:            npm i stylus@latest -g 3. 此时可以创建  .s ...

  4. INFO Dispatcher:42 - Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir

    INFO Dispatcher:42 - Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax ...

  5. A - Shashlik Cooking CodeForces - 1040B

    http://codeforces.com/problemset/problem/1040/B Long story short, shashlik is Miroslav's favorite fo ...

  6. 【模拟与阅读理解】Gym - 101954C Rullete

    http://codeforces.com/gym/101954/problem/C 题意:14行伪代码让你翻译. 坑得yibi #include<stdio.h> #include< ...

  7. Python_环境部署及报错汇总(0)

    一.安装Anaconda Anaconda是一个开源的包.环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换. Anaconda包括Conda.Python以及 ...

  8. css3 伸缩布局 display:flex等

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. MongoDB 备份(mongodump)与恢复(mongorestore)

    MongoDB  备份(mongodump)与恢复(mongorestore) 备份:使用mongodump命令导出所有数据库到指定目录 参数说明: --host:MongoDB所在服务器IP. -- ...

  10. MongoDB常用操作--简介

    mongodb在项目中使用越来越觉得日志方面的记录和查询是远远优于MySQL的,所以对其一些基本的操作进行了整理,以下就是整理的一些规则插入数据: insert插入多组数据:inserrAll修改数据 ...