Asp.net mvc 统一国际奥委会+;WCF&x2B;wsHTTPBinding+;证书授权
我在IIS上有两个用于开发的应用程序。第一个包含所有逻辑和与数据库通信的WCF应用程序(我们称之为服务器)。还有另一个ASP.NET MVC 3应用程序,它引用了WCF应用程序(我们称之为客户端) 我的问题与混合WCF web.config配置与Unity IoC自定义服务主机和自定义行为有关 当所有配置都由Unity完成时,它会创建简单的BasicHttpBinding,但我的要求是通过证书授权使其安全,所以我需要wsHTTPBinding -------------配置BasicHttpBinding------------ 在开始时,请查看WCF的通用统一实现:Asp.net mvc 统一国际奥委会+;WCF&x2B;wsHTTPBinding+;证书授权,asp.net-mvc,wcf,asp.net-mvc-3,unity-container,wcf-security,Asp.net Mvc,Wcf,Asp.net Mvc 3,Unity Container,Wcf Security,我在IIS上有两个用于开发的应用程序。第一个包含所有逻辑和与数据库通信的WCF应用程序(我们称之为服务器)。还有另一个ASP.NET MVC 3应用程序,它引用了WCF应用程序(我们称之为客户端) 我的问题与混合WCF web.config配置与Unity IoC自定义服务主机和自定义行为有关 当所有配置都由Unity完成时,它会创建简单的BasicHttpBinding,但我的要求是通过证书授权使其安全,所以我需要wsHTTPBinding -------------配置BasicHttpBi
internal class UnityInstanceProvider : IInstanceProvider
{
private readonly IUnityContainer container;
private readonly Type contractType;
public UnityInstanceProvider(
[NotNull] IUnityContainer container,
[NotNull] Type contractType)
{
this.container = container;
this.contractType = contractType;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return container.Resolve(contractType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
container.Teardown(instance);
}
}
internal class UnityServiceBehavior : IServiceBehavior
{
private readonly IUnityContainer container;
public UnityServiceBehavior(
[NotNull] IUnityContainer container)
{
this.container = container;
}
#region IServiceBehavior Members
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
{
if (endpointDispatcher.ContractName != "IMetadataExchange")
{
endpointDispatcher.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(container, serviceDescription.ServiceType);
}
}
}
}
#endregion
}
public class UnityServiceHost : ServiceHost
{
private readonly IUnityContainer container;
public UnityServiceHost(
[NotNull] IUnityContainer container,
[NotNull] Type serviceType,
Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
this.container = container;
}
protected override void OnOpening()
{
base.OnOpening();
if (Description.Behaviors.Find<UnityServiceBehavior>() == null)
{
Description.Behaviors.Add(new UnityServiceBehavior(container));
}
}
}
public class UnityServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
IUnityContainer container = new UnityContainer();
UnityContainerConfigurator.Configure(container);
return new UnityServiceHost(container, serviceType, baseAddresses);
}
}
它很好用。。。所以可以肯定的是,这个问题并不是和错误的wsHttpBinding配置有关,而是将Unity+wsHttpBinding与web.config结合起来
有人能帮我解决这个问题吗
丹尼尔好的,我想起来了
Ladislav你是对的,它应该显示一个例外。
UnityDependencyResolver只是简单地捕捉到了它
internal class UnityDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer container;
public UnityDependencyResolver([NotNull] IUnityContainer container)
{
this.container = container;
}
#region IDependencyResolver Members
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
内部类unitydependencysolver:idependencysolver
{
专用只读IUnityContainer容器;
公共UnityDependencyResolver([NotNull]IUnityContainer容器)
{
this.container=容器;
}
#区域IDependencyResolver成员
公共对象GetService(类型serviceType)
{
尝试
{
返回容器解析(serviceType);
}
抓住
{
返回null;
}
}
公共IEnumerable GetServices(类型serviceType)
{
尝试
{
返回容器.ResolveAll(serviceType);
}
抓住
{
返回新列表();
}
}
我还必须为证书显式设置证书位置:
<serviceCertificate findValue="CN=myClientCert"
storeName="My"
x509FindType="FindBySubjectDistinguishedName"
storeLocation="LocalMachine"
/>
<clientCertificate findValue="CN=myClientCert" storeName="My"
x509FindType="FindBySubjectDistinguishedName"
storeLocation="LocalMachine"
/>
现在它工作正常。这看起来更像是您自己代码中的问题。如果Unity无法创建实例,并且如果它尝试创建实例,它将调用构造函数,那么它将触发异常-这种调用不会导致
null
。
<endpoint address="http://localhost/wcf-app/SecurityService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISecurityService"
contract="SecurityServiceReference.ISecurityService" name="BasicHttpBinding_ISecurityService" />
container.RegisterType<SecurityServiceClient>(new InjectionConstructor());
var securityService = DependencyResolver.Current.GetService<SecurityServiceClient>();
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="myNamespace.SecurityService">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
name="wsHttpEndpoint" contract="myNamespace.ISecurityService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="CN=myClientCert" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<wsHttpBinding>
<binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
<behaviors>
<endpointBehaviors>
<behavior name="CertBehavior">
<clientCredentials>
<clientCertificate findValue="CN=myClientCert"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
var securityService = DependencyResolver.Current.GetService<SecurityServiceClient>();
var client = new SecurityServiceReference.SecurityServiceClient();
internal class UnityDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer container;
public UnityDependencyResolver([NotNull] IUnityContainer container)
{
this.container = container;
}
#region IDependencyResolver Members
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
<serviceCertificate findValue="CN=myClientCert"
storeName="My"
x509FindType="FindBySubjectDistinguishedName"
storeLocation="LocalMachine"
/>
<clientCertificate findValue="CN=myClientCert" storeName="My"
x509FindType="FindBySubjectDistinguishedName"
storeLocation="LocalMachine"
/>