Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在配置文件中使用多个搜索条件查找WCF服务证书_C#_.net_Wcf_X509certificate - Fatal编程技术网

C# 在配置文件中使用多个搜索条件查找WCF服务证书

C# 在配置文件中使用多个搜索条件查找WCF服务证书,c#,.net,wcf,x509certificate,C#,.net,Wcf,X509certificate,我想知道,有没有办法使用.config文件中的几个搜索条件来查找WCF服务证书 例如,如果我想通过使用者名称查找证书,那么我的配置将包含以下行: <serviceCertificate findValue="host.domain.com" storeLocation="LocalMachine" storeName="My"

我想知道,有没有办法使用
.config
文件中的几个搜索条件来查找WCF服务证书

例如,如果我想通过使用者名称查找证书,那么我的配置将包含以下行:

        <serviceCertificate findValue="host.domain.com"
                            storeLocation="LocalMachine"
                            storeName="My"
                            x509FindType="FindBySubjectName"/>

那么
.config
-文件呢?

编写一个自定义服务行为,您将能够从配置中提供您的应用程序策略和使用者名称,并在证书存储上执行两次连续查找

public class ServerCertificateServiceBehavior : IServiceBehavior
{
    private X509Certificate2 certificate;

    public ServerCertificateServiceBehavior(StoreName storeName, StoreLocation storeLocation, string subjectName, string applicationPolicy)
    {
        X509Store store = new X509Store(storeName, storeLocation);
        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

        certificate = store
            .Certificates
            .Find(X509FindType.FindByApplicationPolicy, applicationPolicy, false)
            .Find(X509FindType.FindBySubjectName, subjectName, false)
            .Cast<X509Certificate2>()
            .SingleOrDefault();
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        serviceHostBase.Credentials.ServiceCertificate.Certificate = this.certificate;
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
}
配置变为:

<behaviors>
  <serviceBehaviors>
    <behavior name="YourServiceBehaviorConfiguration">
      <!-- ... -->
      <serverCertificate storeLocation="LocalMachine"
                         storeName="My"
                         subjectName="host.domain.com"
                         applicationPolicy="1.3.6.1.5.5.7.3.1" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add name="serverCertificate" type="Extensions.ServerCertificateServiceBehaviorExtensionElement, Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>


X509Certificate2Collection.Find文档中的示例仅显示按时间有效的查找(
X509FindType.FindByTimeValid
)。我看不出在哪里可以执行“按应用程序查找”策略。示例代码中唯一在配置中不可用的参数是
X509Store.Open
调用中使用的
OpenFlags
,而且没有其他可用参数。@Paciv:问题不在于
X509Certificate2Collection.Find
。它允许按应用程序策略查找,请相信我(请参阅更新的问题)。:)问题是如何在配置文件中创建搜索条件链接,就像在代码中一样。很抱歉,在您接受答案时,我更改了一点答案(添加了一种从配置而不是代码中执行的方法)。请检查更新的解决方案是否仍然有效。@Paciv:谢谢,在我看来,此解决方案将有所帮助。我会试试看。我不知道你的代码是如何工作的,因为即使在最新的.net 4.7中,
findbyaapplicationpolicy
仍然不受支持@Mono中的codenamezero似乎是的。它应该在Windows上工作。。。证书存储非常依赖于操作系统/运行时环境。
public class ServerCertificateServiceBehaviorExtensionElement : BehaviorExtensionElement
{
    [ConfigurationProperty("applicationPolicy", IsRequired = true)]
    public string ApplicationPolicy
    {
        get
        {
            return (string)base["applicationPolicy"];
        }
        set
        {
            base["applicationPolicy"] = value;
        }
    }

    [ConfigurationProperty("subjectName", IsRequired = true)]
    public string SubjectName
    {
        get
        {
            return (string)base["subjectName"];
        }
        set
        {
            base["subjectName"] = value;
        }
    }

    [ConfigurationProperty("storeLocation", DefaultValue = 2)]
    public StoreLocation StoreLocation
    {
        get
        {
            return (StoreLocation)base["storeLocation"];
        }
        set
        {
            base["storeLocation"] = value;
        }
    }

    [ConfigurationProperty("storeName", DefaultValue = 5)]
    public StoreName StoreName
    {
        get
        {
            return (StoreName)base["storeName"];
        }
        set
        {
            base["storeName"] = value;
        }
    }

    public override Type BehaviorType
    {
        get { return typeof(ServerCertificateServiceBehavior); }
    }
    protected override object CreateBehavior()
    {
        return new ServerCertificateServiceBehavior(
                this.StoreName, 
                this.StoreLocation, 
                this.SubjectName, 
                this.ApplicationPolicy);
    }
}
<behaviors>
  <serviceBehaviors>
    <behavior name="YourServiceBehaviorConfiguration">
      <!-- ... -->
      <serverCertificate storeLocation="LocalMachine"
                         storeName="My"
                         subjectName="host.domain.com"
                         applicationPolicy="1.3.6.1.5.5.7.3.1" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add name="serverCertificate" type="Extensions.ServerCertificateServiceBehaviorExtensionElement, Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>