减少 WCF 配置中的重复嵌套标识
Posted
技术标签:
【中文标题】减少 WCF 配置中的重复嵌套标识【英文标题】:Reduce repeated nested identity in WCF config 【发布时间】:2013-11-18 18:02:40 【问题描述】:我的 WCF 应用程序的 web.config 定义了一系列端点,如下所示:
<system.serviceModel>
<services>
<service behaviorConfiguration="whatever" name="MyService">
<endpoint name="Endpoint1" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract1">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
<endpoint name="Endpoint2" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract2">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
<endpoint name="Endpoint3" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract3">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
<endpoint name="Endpoint4" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract4">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
我想做的是
<system.serviceModel>
<services>
<service behaviorConfiguration="whatever" name="MyService">
<endpoint name="Endpoint1" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract1" />
<endpoint name="Endpoint2" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract2" />
<endpoint name="Endpoint3" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract3" />
<endpoint name="Endpoint4" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract4" />
在另一个地方指定了一次默认身份定义(即使只是 system.serviceModel 元素中的***)。
基本上我想 DRY,因为配置自始至终都是一致的。我需要 SO 的帮助是在哪里可以找到“所有端点的默认身份”配置元素。 MSDN 没有提供太多帮助,我不确定在哪里反映 .NET 库以查看在应用启动时读取 web.configs 时如何解释。
【问题讨论】:
您可以从您的代码中配置您的服务,因此您可以手动编写自己的配置处理程序和初始化服务。 这一切都需要来自 XML 配置,最好是在 web.config 中。我知道我可以在代码中配置它,但这不是我们所拥有的。 【参考方案1】:总结
使用Standard Endpoints 创建具有适当身份信息的自定义端点,可以从配置文件中进行配置。
详情
感谢您的提问! WCF 服务的统一配置以减少配置开销是我一直想要研究的,而你的问题正好给了我这样做的借口。
我使用 Standard Endpoints 解决了这个问题,它自 .NET 4 以来就一直存在。大部分工作是通过从 StandardEndpointElement
继承来完成的:
namespace WcfEx
public class X509EndpointElement : StandardEndpointElement
private static string _findValueKey = "findValue";
private static string _storeNameKey = "storeName";
private static string _storeLocationKey = "storeLocation";
private static string _x509FindTypeKey = "x509SearchType";
public virtual string FindValue
get return base[_findValueKey] as string;
set base[_findValueKey] = value;
public virtual StoreName StoreName
get return this[_storeNameKey] is StoreName ? (StoreName) this[_storeNameKey] : (StoreName) 0;
set this[_storeNameKey] = value;
public virtual StoreLocation StoreLocation
get
return this[_storeLocationKey] is StoreLocation
? (StoreLocation) this[_storeLocationKey]
: (StoreLocation) 0;
set this[_storeLocationKey] = value;
public virtual X509FindType X509FindType
get return this[_x509FindTypeKey] is X509FindType ? (X509FindType) this[_x509FindTypeKey] : (X509FindType) 0;
set this[_x509FindTypeKey] = value;
protected override ConfigurationPropertyCollection Properties
get
ConfigurationPropertyCollection properties = base.Properties;
properties.Add(new ConfigurationProperty(_findValueKey, typeof (string), null,
ConfigurationPropertyOptions.None));
properties.Add(new ConfigurationProperty(_storeNameKey, typeof (StoreName), null,
ConfigurationPropertyOptions.None));
properties.Add(new ConfigurationProperty(_storeLocationKey, typeof (StoreLocation), null,
ConfigurationPropertyOptions.None));
properties.Add(new ConfigurationProperty(_x509FindTypeKey, typeof (X509FindType), null,
ConfigurationPropertyOptions.None));
return properties;
protected override Type EndpointType
get return typeof (ServiceEndpoint);
protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription contract)
return new ServiceEndpoint(contract);
protected override void OnApplyConfiguration(ServiceEndpoint endpoint,
ServiceEndpointElement serviceEndpointElement)
endpoint.Address = new EndpointAddress(endpoint.Address.Uri,
EndpointIdentity.CreateX509CertificateIdentity(
GetCertificateFromStore()));
protected override void OnApplyConfiguration(ServiceEndpoint endpoint,
ChannelEndpointElement channelEndpointElement)
endpoint.Address = new EndpointAddress(endpoint.Address.Uri,
EndpointIdentity.CreateX509CertificateIdentity(
GetCertificateFromStore()));
private X509Certificate2 GetCertificateFromStore()
var certificateStore = new X509Store(StoreName, StoreLocation);
certificateStore.Open(OpenFlags.ReadOnly);
var matchingCertificates = certificateStore.Certificates.Find(X509FindType, FindValue, false);
X509Certificate2 matchingCertificate = null;
if (matchingCertificates.Count > 0)
matchingCertificate = matchingCertificates[0];
else throw new InvalidOperationException("Could not find specified certificate");
certificateStore.Close();
return matchingCertificate;
protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement)
protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement)
对上述代码的快速总结:
此类可以在 .config 文件中可见 - 因此可以通过配置设置它的属性; 有四个属性指定选择X509证书的参数; 在此类生命周期的某个时刻,端点地址设置为使用满足搜索条件的证书指定的身份。你需要一个集合类来保存上述类的元素:
namespace WcfEx
public class X509EndpointCollectionElement : StandardEndpointCollectionElement<ServiceEndpoint, X509EndpointElement>
.config 文件的 system.serviceModel
部分如下所示:
<system.serviceModel>
<extensions>
<endpointExtensions>
<add name="x509Endpoint" type="WcfEx.X509EndpointCollectionElement, WcfEx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</endpointExtensions>
</extensions>
<standardEndpoints>
<x509Endpoint>
<standardEndpoint storeLocation="LocalMachine" storeName="TrustedPeople" findValue="cert name" x509SearchType="FindBySubjectName"/>
</x509Endpoint>
</standardEndpoints>
<services>
<service name="WcfHost.Service1">
<endpoint address="" binding="wsHttpBinding" contract="WcfHost.IService1" kind="x509Endpoint" >
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
注意事项:
请非常注意此处type
属性的值 - 它需要与typeof (X509EndpointElement).AssemblyQualifiedName
完全相同。
注册后,我们可以将相关配置添加到standardEndpoints
元素中。
我们使用kind
属性将端点“标记”为具有自定义功能。
【讨论】:
抱歉 - 我不清楚。我只是指配置sn-p的第4行。 赏金我最终可能会采用的出色解决方案。我与团队的负责人分享了他是否想在未来融入这些变化。 很高兴您发现我的解决方案很有用。再次感谢您发布问题 - WCF 配置中的重复是我过去也一直在努力解决的问题。似乎可以推广类似的技术以在其他场景中维护 DRY WCF 配置。我从回答你的问题中学到了很多东西。以上是关于减少 WCF 配置中的重复嵌套标识的主要内容,如果未能解决你的问题,请参考以下文章
在 app.config 文件中配置 wcf 超时 [重复]