具有相互 SSL(服务和客户端之间)的自托管 WCF 服务失败并显示 403 Forbidden

2023-12-02

我正在尝试在以下设备之间设置相互 SSL 的演示自托管WCF 服务和客户端应用程序(现在是命令提示符)。最后我试图找到一个解决方案运输安全(不是消息安全)在使用证书进行传入连接的服务器和多个客户端之间,每个客户端都有单独的证书,我可以使用这些证书来唯一地标识每个客户端。

我尝试了许多不同的方法,但没有一个有效(我无法找到我一直在尝试做的事情的确切例子)。每次我认为我已经接近目标时,当我尝试调用该服务时,最终都会在客户端中出现异常。我遇到的最常见的异常是:

“The HTTP request was forbidden with client authentication scheme 'Anonymous'.”
Inner exception: "The remote server returned an error: (403) Forbidden."

有谁对我可能做错了什么有什么想法,或者更好地了解如何在上述场景中设置相互 SSL?

完全披露 - 截至目前,我在同一台计算机上运行客户端和服务器。不确定这是否重要。

下面的配置片段

服务和客户端代码相对简单,所以我非常有信心我已经让它们工作了。应用程序配置(特别是绑定和行为)和证书“更有趣”,所以我对此不太有信心。

我如何创建证书(逐字实际命令)

makecert -pe -n "CN=SelfSignedCA" -ss Root -sr LocalMachine  -a sha1 -sky signature -r -sv "SelfSignedCA.cer" "SelfSignedCA.pvk"
makecert -pe -n "CN=system" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1  -in "SelfSignedCA" -is Root -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 Service.cer
makecert -pe -n "CN=client1" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1  -in "SelfSignedCA" -is Root -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 Client1.cer

将证书与端口关联(逐字实际命令)

netsh http add urlacl url=https://+:44355/MyService/ user=EVERYONE

服务器设置

绑定:

  <wsHttpBinding>
    <binding name="CustomBinding">      
      <security mode="Transport">
        <transport clientCredentialType="Certificate"/>
      </security>
    </binding>
  </wsHttpBinding>

行为:

    <serviceBehaviors>
      <behavior name="">
      <!--
      <serviceCredentials>
        <serviceCertificate
           findValue="system"
           storeLocation="LocalMachine"
           storeName="My"
           x509FindType="FindBySubjectName"/>
      </serviceCredentials>
      -->
      <serviceAuthorization
         serviceAuthorizationManagerType=
              "ClientAuthorization.ClientCertificateAuthorizationManager, Simulator.Service.SideA" />
    </behavior>
  </serviceBehaviors>

Client

绑定:

  <wsHttpBinding>
    <binding name="CustomBinding">      
      <security mode="Transport">
        <transport clientCredentialType="Certificate"/>
      </security>
    </binding>
  </wsHttpBinding>

行为

  <endpointBehaviors>
    <behavior name="ChannelManagerBehavior">
      <clientCredentials>
         <clientCertificate findValue="client1"
                           storeLocation="LocalMachine"
                           storeName="My"
                           x509FindType="FindBySubjectName" />
        <!--
        <serviceCertificate>
          <authentication certificateValidationMode="PeerOrChainTrust"/>
        </serviceCertificate>
        -->
      </clientCredentials>
     </behavior>
  </endpointBehaviors>

UPDATE

因此,我向服务器添加了一个自定义用户名和密码验证器,试图覆盖默认行为,并且无论提供的凭据如何都始终允许(同样,我真的不希望用户名/密码验证)。该验证器永远不会被调用。客户端仍然获得“身份验证方案‘匿名’”。例外。

服务行为更新

  <serviceCredentials>
    <userNameAuthentication 
      userNamePasswordValidationMode="Custom"
      customUserNamePasswordValidatorType=
        "Service.ClientAuthorization.ClientUserNamePasswordValidatorManager, Service.SideA" />
  </serviceCredentials>

这是演示供您参考。我在win7 + vs2010 +同一台机器上的客户端-服务器下测试了它。

服务器端:

[ServiceContract(Name="CalculatorService")]
    public interface ICalculatorService {
        [OperationContract]
        int Add(int x, int y);
    }

public class CalculatorService : ICalculatorService {
        public Int32 Add(Int32 x, Int32 y) {
            Console.WriteLine("{0}: service method called (x = {1}, y = {2})",
                Thread.CurrentThread.ManagedThreadId, x, y);
            return x + y;
        }
    }

class Program {
        static void Main(string[] args) {
            ServicePointManager.ServerCertificateValidationCallback +=
                (sender, certificate, chain, sslPolicyErrors) => true;

            using (var serviceHost = new ServiceHost(typeof(CalculatorService))) {
                serviceHost.Opened += delegate {
                    Console.WriteLine("{0}: service started", 
                        Thread.CurrentThread.ManagedThreadId);
                };
                serviceHost.Open();
                Console.Read();
            }
        }
    }

<?xml version="1.0" encoding="utf-8" ?> <configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="transportSecurity">
                    <security mode="Transport">
                        <transport clientCredentialType="Certificate"/>
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>

        <services>
            <service name="WcfService.CalculatorService">
                <endpoint address="https://hp-laptop:3721/calculatorservice"
                          binding="wsHttpBinding"
                          bindingConfiguration="transportSecurity"
                          contract="Contract.ICalculatorService" />
            </service>
        </services>
    </system.serviceModel> </configuration>

客户端:

class Program {
        static void Main(string[] args) {
            using (var channelFactory =
                new ChannelFactory<ICalculatorService>("calculatorservice")) {
                ICalculatorService proxy = channelFactory.CreateChannel();
                Console.WriteLine(proxy.Add(1, 2));
                Console.Read();
            }
            Console.Read();
        }
    }

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="transportSecurity">
                    <security mode="Transport">
                        <transport clientCredentialType="Certificate"/>
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <behaviors>
            <endpointBehaviors>
                <behavior name="defaultClientCertificate">
                    <clientCredentials>
                        <clientCertificate 
                            storeLocation="LocalMachine" 
                            storeName="My" 
                            x509FindType="FindBySubjectName" 
                            findValue="client1"/>
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <client>
            <endpoint name="calculatorservice" behaviorConfiguration="defaultClientCertificate"
                      address="https://hp-laptop:3721/calculatorservice"
                      binding="wsHttpBinding"
                      bindingConfiguration="transportSecurity"
                      contract="Contract.ICalculatorService"/>
        </client>
    </system.serviceModel>
</configuration>

证书创建:

自建CA

makecert -n "CN=RootCA" -r -sv c:\rootca.pvk c:\rootca.cer

创建后,通过证书控制台将此证书导入到“受信任的根证书”中。这是停止您提到的异常的步骤。

服务计划证书

makecert -n "CN=hp-laptop" -ic c:\rootca.cer -iv c:\rootca.pvk -sr LocalMachine -ss My -pe -sky 交换

请注意,上面的 CN 值应与服务地址的 DNS 部分匹配。例如hp-laptop 是我的计算机名称。服务端点的地址将是“https://google.com:/..."。(由于某些 stackoverflow 规则,请将 google dot com 替换为 'hp-laptop')。

向服务程序注册服务证书:

netsh http 添加 sslcert ipport=0.0.0.0:3721 certhash=‎6c78ad6480d62f5f460f17f70ef9660076872326 appid={a0327398-4069-4d2d-83c0-a0d5e6cc71b5}

certhash 值是服务程序证书的指纹(使用证书控制台进行检查)。 appid 是服务程序文件“AssemblyINfo.cs”中的 GUID。

客户端程序证书:

makecert -n "CN=client1" -ic c:\rootca.cer -iv c:\rootca.pvk -sr LocalMachine -ss My -pe -sky 交换

更新:根据typhoid对此解决方案的经验,由于该服务器中受信任的根权限过多,“匿名”异常仍然存在。伤寒提供了两个链接来解决这个问题。

http://support.microsoft.com/kb/2464556

http://blog.codit.eu/post/2013/04/03/Troubleshooting-SSL-client-certificate-issue-on-IIS.aspx

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有相互 SSL(服务和客户端之间)的自托管 WCF 服务失败并显示 403 Forbidden 的相关文章

  • 如何使用 php 通过 https 下载文件

    我需要使用 PHP 下载 xml 文件 我可以在对文件进行curl 调用时通过设置以下选项来读取文件的内容 curl setopt http CURLOPT SSL VERIFYPEER false curl setopt http CUR
  • WCF - 将空元素转换为可为空的本机类型

    将 SOAP 字段元素留空会导致本机类型出现强制转换错误 遗憾的是 由于客户端限制 无法使用 xsi nil true 将 WCF 协定本机类型标记为 nullable 似乎不足以阻止将以下错误返回给客户端 字符串 不是有效的布尔值 在 S
  • 带有客户端证书的android webview

    我尝试了几天使用嵌入在应用程序中的客户端证书的Web视图 但在我看来 android sdk没有提供任何方法来做到这一点 是否有回调来拦截服务器发送的质询 有没有办法将 webview 与客户端证书一起使用并发出 https 请求 因为我也
  • SSL握手时是否检查服务器域名

    在 SSL 握手期间 是否在 SSL 握手期间检查服务器的域名 我的意思是 是否根据服务器运行的域检查了经过认证的服务器中的域名 示例 假设服务器证书具有域 mydomain com 如果服务器在域 someotherdomain com
  • 当SESSION_COOKIE_SECURE = True时如何在HTTP中获取一些用户身份信息

    以下是我正在开发的网站的简短描述 公共页面可以通过 HTTP 或 HTTPS 访问 其他一些页面 认证页面 账户详情页面等 需要通过HTTPS访问 Apache2 负责进行相关的 HTTP 到 HTTPS 链接重定向 我使用标准 Djang
  • 快速修复:如何在 Python 中使用 SSL

    对不起我的英语不好 我在连接用 python 开发的客户端 quckfix 时遇到问题 配置文件没有像我想要的那样响应 如果我将路径 不正确的路径 强制错误 更改为文件 pem 并重新启动应用程序 该应用程序什么也不做 只是保持正常运行 就
  • 有状态 WCF Web 服务

    我是 WCF 新手 我一直在尝试在 Web 服务中使用会话状态 我设法使用number http www codeproject com KB session SessionWithWS aspx msg 3227646 of http w
  • SMTP:无法连接套接字:无法找到套接字传输“ssl”

    我一直在尝试在 WAMP 上使用 Pear 发送电子邮件通过 GMail 花了几个小时将其全部设置并找出我遇到的所有错误后 我以为我已经很接近了 直到我开始收到此错误 Failed to connect to ssl smtp gmail
  • 在 SSLwrapp() 之前在原始套接字上接收/发送,Python

    我想知道在包装原始套接字之前是否可以在原始套接字上接收 发送数据 我已经查看了文档并搜索了它 但找不到任何具体内容 我基本上想做的事情 client addr listeningSocket accept client recv 32 cl
  • Java 密钥库 - 以编程方式从密钥库文件中选择要使用的证书

    我有一个 java 密钥库文件 其中包含多个客户端证书 我希望在 Java 应用程序中仅选择其中一个证书来连接到服务 有没有一种简单的方法可以做到这一点 到目前为止 我找到解决方案的唯一方法是使用原始密钥库文件中的客户端证书详细信息 通过其
  • 如何向 node-http-proxy 响应添加标头

    我需要在第三方服务上解决CORS 所以我想构建一个代理来添加标头 Access Control Allow Origin 为什么这段代码没有添加标题 httpProxy require http proxy var URL https th
  • 远程服务器返回错误:NotFound。银光+WCF

    我正在尝试调用网络服务几个小时 我添加了 clientaccesspolicy xml
  • 使用请求验证 SSL 证书

    我正在尝试验证 SSL 但它不起作用 我在浏览器上访问了我想要访问的机密网站 在 Chrome 上 我单击了储物柜 gt 证书 gt 详细信息 gt 复制到文件 gt base64 gt cert cer 我的代码是 test reques
  • 如何使用自签名证书为 TLS 创建 iOS NWConnection?

    我正在尝试将 Apple 的新 NWConnection 类用于我的 MQTT 客户端 为了进行测试 我需要能够创建到本地测试代理的 TLS 连接 该代理具有自签名证书 到目前为止 我只是使用以下命令设置连接 self connection
  • Task.Delay 值得取消吗?

    我最近使用取消模式重新实现了一大堆异步 WCF 服务方法 我在很多地方都看到过这种模式的描述 您可以在其中等待Task WhenAny在已启动的任务和 Task Delay 上 当然 现有任务是不可取消的 但这有望在以后的版本中得到解决 就
  • 使用 gmail 和 Indy 发送电子邮件

    我正在尝试使用 gmail 从 Delphi 发送电子邮件 我有 Indy 10 5 9 0 和 Delphi XE3 我从以下位置获得了示例代码 http www andrecelestino com delphi xe envio de
  • 有人可以推荐客户 ssl 证书服务吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在查看各种 SSL 提供商 但它们似乎都提供 电子邮件证书 它可以兼作可以安装到浏览器中的客户端证
  • 如何从Windows服务公开restful接口?

    我编写了一个公开restful接口的wcf服务 现在我使用iis作为wcf服务主机 除了暴露其余部分之外 我还需要对我的应用程序执行一些操作 为此 我必须将我的应用程序作为 Windows 服务运行 但是使用iis作为主机不会使我的wcf服
  • 我需要编写什么代码才能使用 HTTPS?

    在标准的 小册子 站点中 我有一个子系统 其中私人数据在一系列页面中来回传递 该网站已完成 现在可以在没有 HTTPS 的情况下运行 有人可以向我指出在网站的安全部分实施 HTTPS 所需执行的步骤列表吗 作为程序员 您唯一需要做的就是检查
  • WCF 错误:相对端点地址

    嗯 对 WCF 还很陌生 我想我有点搞砸了 这就是我到目前为止所做的 我在 IIS 中托管了我的 WCF 服务 首先是合同 using System using System Collections Generic using System

随机推荐

  • 如何在空手道中为 json 数组设置动态值

    我有一个 json 文件 每个 post 请求都需要 uniq 值 uniqId 55555 对于所有 uniq id 我需要传递相同的 uniqId 到目前为止 我只能设置 endtoEndid 无法设置invoiceNum 和txnVa
  • JobIntentService 的 onHandleWork() 的最大作业执行时间是多少?

    我遇到了一个SecurityException在 Android 8 上崩溃targetSDK 26使用时JobIntentService 这是来自 JobIntentService 文档 那么最大作业执行时间限制是多少 如果超过它 是否可
  • 测试使用 PersistentEntityResourceAssembler 的自定义 RepositoryRestController

    我有一个RepositoryRestController公开一些持久性实体的资源 我的控制器上有一个方法 需要PersistentEntityResourceAssembler帮助我自动生成资源 RepositoryRestControll
  • 使用块将数据传递回视图控制器

    我在看这个问题 答案之一展示了如何使用块向后传递数据查看prepareForSegue方法 我的理解是这种方法确实应该用于向前传递数据 而不是向后传递数据 我想尝试为此目的进行阻止 将数据传递回另一个 viewController 我的问题
  • 在Python中的文件末尾声明函数[重复]

    这个问题在这里已经有答案了 是否可以在不完全定义函数的情况下调用该函数 当尝试这样做时 我收到错误 函数名未定义 我有 C 背景 所以这个问题困扰着我 在工作之前声明该函数 def Kerma return energy mass prin
  • 如何启用 Core Plot 饼图中的某个部分的触摸选择?

    我正在使用 Core Plot 框架来绘制饼图 并且在绘制饼图本身时没有任何问题 但是 我需要饼图本质上是交互式的 即 如果我点击饼图中的任何特定部分 它应该触发导航到显示该特定部分的详细信息的页面 我尝试使用该方法 void pieCha
  • Android 在应用程序中集成 google+

    任何人都可以在 Android 应用程序中使用 Google 吗 我搜索了同样的事情 但什么也没找到 如果有人有任何想法或相关代码 请在此发布 Thanks 目前还没有公共 API 但您可以在此处注册更新 https services go
  • 如何将行追加到 R 数据框

    我查看了 StackOverflow 但找不到特定于我的问题的解决方案 该解决方案涉及将行附加到 R 数据框 我正在初始化一个空的 2 列数据框 如下所示 df data frame x numeric y character 然后 我的目
  • 浮点固定长度数字格式化c#

    我想在 C 中按如下方式格式化浮点数 以便 C 中浮点数的整个宽度是固定长度 python 等效格式说明符 6 2f 我不希望它在左侧填充 0 但是用空白填充 100 00 90 45 7 23 0 00 到目前为止我已经尝试过什么 str
  • 如何使用 Firemonkey 显示 Android 内存中的可用文件

    在 Delphi for Windows 中 有TOpenDialog和命令如FindFirst 在 Firemonky Android 中没有 TOpenDialog but according to many forumsFindFir
  • 从回调和内联自调用函数访问父函数变量

    我相信乍一看这两个自调用函数是相同的 它们之间的唯一区别是在第一个函数中我传递回调函数 然后通过参数对象执行 而在第二个函数中通过使函数自调用来做同样的事情 现在来访问第一个示例中的父变量 名称是 undefined 而在第二个示例中 它是
  • Java WeakHashMap什么时候会清理null key?

    在下面的代码中nameRef get 为 null 之后name null and System gc import java lang ref WeakReference public class Main public static v
  • 内部服务器错误 - Azure 应用服务自定义控制器

    我有一个 Azure 移动应用服务 不是旧的移动服务 带有多个自定义控制器 并且流程运行完美 今天发生了一个错误 关于Internal Server Error 我附加了调试器并逐步执行代码 控制器到达末尾没有任何错误并返回Ok 因此我一直
  • 样式占位符文本的颜色在 Firefox 中被静音

    我已经使用相关供应商前缀更改了占位符的颜色 并且它在其他浏览器中正确显示 但由于某种原因 Firefox 使颜色稍微静音 moz placeholder input moz placeholder color Black 我都用过 moz
  • Selenium VBA - 退出子进程而不关闭浏览器窗口

    如何在不关闭浏览器窗口的情况下退出子 宏 代码完成后 Chrome 浏览器会自动关闭 例如我有 Sub test Dim driver As New ChromeDriver driver Get http www google com E
  • 有没有办法让使用服务器发送的事件持久化?

    我需要运行一个每秒更新一次用户浏览器的脚本 我的需要是从服务器到客户端的单向通信 为此 我实施了服务器发送的事件从我的服务器轮询到用户的客户端 问题是允许用户 通过打开多个浏览器选项卡 打开与服务器的多个连接 这是一个问题 因为它增加了服务
  • 如何在 Xcode 8 中使用 CoreData?

    我正在尝试使用 CoreData 但是当我将其添加到我的项目中时 我只得到两种新方法 NSPersistentContainer persistentContainer and void saveContext 现在我无法使用旧方法Core
  • PaintEvent 不过度绘制

    我有一个 C 语言的 Windows 窗体应用程序 带有绘图面板和一个用于绘制线条的按钮 单击该按钮时 可以为 2 个随机点绘制一条线 Pen p new Pen Color Black 5 point for start Point ps
  • SSLException:收到致命警报:Java 1.7 升级后非法参数

    连接到 LDAP 时从 Tomcat 5 升级 Tomcat 7 会出现错误 main READ TLSv1 Alert length 2 main RECV TLSv1 ALERT fatal illegal parameter main
  • 具有相互 SSL(服务和客户端之间)的自托管 WCF 服务失败并显示 403 Forbidden

    我正在尝试在以下设备之间设置相互 SSL 的演示自托管WCF 服务和客户端应用程序 现在是命令提示符 最后我试图找到一个解决方案运输安全 不是消息安全 在使用证书进行传入连接的服务器和多个客户端之间 每个客户端都有单独的证书 我可以使用这些