我想在基于 ASP.NET v4.0 并通过表单身份验证保护的已创建 IIS 7.5 网站上托管 REST 完整的 WCF 4.0 服务。因此,我尝试使用混合模式身份验证 (aspNetCompatibilityEnabled="false") 配置我的 WCF 堆栈,并将服务主机配置为根本不使用任何安全性,但长期以来,我的所有努力都完全没有成功。当我尝试在一段时间后从浏览器调用我的服务时,与主机的连接在没有响应的情况下关闭,并且我的浏览器引发错误,表明与目标网站的连接已关闭而没有任何响应。
但是,如果我在 Application_BeginRequest 中编写一个虚拟代码以使用 FormsAuthentication.Authenticate 对表单身份验证模块中的虚拟用户进行身份验证,或者在经过身份验证的浏览器会话中调用该服务,那么一切正常并且该服务被成功调用。
我试图使用 WCF 跟踪找到导致这种奇怪行为的问题。我从生成的 svclog 文件中发现的是这个异常:
消息:对象引用未设置为对象的实例。
StackTrace:
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.get_LogonUserIdentity() System.ServiceModel.Channels.HttpChannelListener.ValidateAuthentication(IHttpAuthenticationContext authenticationContext) System.ServiceModel.Channels.HttpRequestContext.ProcessAuthentication() System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceived(HttpRequestContext上下文,动作回调)
关于这个问题的任何想法?
更新:我什至将网站的身份验证模式设置为“无”并授权匿名用户。还是一样的结果。没有改变。问题是我可以在 ASP.NET 网站上使用未经身份验证的 WCF RESTfull 服务和 aspNetCompatibilityEnabled="false" 吗???
更具体地说,我试图做的是:
- 以 .svc 文件的形式实现了我的 WCF 服务
- 在我的 web.config 文件中配置 WCF 如下(注意 AspNetCompatibilityEnabled="false"):
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="false" />
</system.serviceModel>
- 像这样创建和使用我自己的 ServiceHostFactory:
public class MyServiceHostFactory : ServiceHostFactoryBase
{
#region Methods
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
var type = Type.GetType(constructorString);
var host = new WebServiceHost(type, baseAddresses);
var serviceBehavior = host.Description.Behaviors.OfType<ServiceBehaviorAttribute>().Single();
serviceBehavior.ConcurrencyMode = ConcurrencyMode.Multiple;
serviceBehavior.MaxItemsInObjectGraph = int.MaxValue;
var metadataBehavior = host.Description.Behaviors.OfType<ServiceMetadataBehavior>().SingleOrDefault();
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(metadataBehavior);
}
var debugBehavior = host.Description.Behaviors.OfType<ServiceDebugBehavior>().SingleOrDefault();
if (debugBehavior == null)
{
debugBehavior = new ServiceDebugBehavior();
host.Description.Behaviors.Add(debugBehavior);
}
metadataBehavior.HttpGetEnabled = true;
debugBehavior.IncludeExceptionDetailInFaults = true;
var binding = new WebHttpBinding { MaxBufferPoolSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue };
binding.Security.Mode = WebHttpSecurityMode.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
WebHttpBehavior webHttpBehavior = new WebHttpBehavior { HelpEnabled = true };
foreach (var contract in type.GetInterfaces().Where(i => i.GetCustomAttributes(typeof(ServiceContractAttribute), true).Length > 0))
{
var endpoint = host.AddServiceEndpoint(contract, binding, "");
endpoint.Behaviors.Add(webHttpBehavior);
}
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
return host;
}
#endregion
}