使用Forms身份验证与ASP.NET并行托管无身份验证的WCF REST服务

时间:2012-10-24 07:36:01

标签: asp.net .net wcf iis-7.5

我想在已经创建的基于ASP.NET v4.0的IIS 7.5网站上托管REST-full WCF 4.0服务,并通过表单身份验证加以保护。因此,我尝试使用混合模式身份验证(aspNetCompatibilityEnabled =“false”)配置我的WCF堆栈,并将服务主机配置为根本不使用安全性,但是很长时间,我的所有努力都完全失败了。当我尝试在一段时间后从浏览器调用我的服务时,关闭主机的连接没有响应,我的浏览器引发错误,指示与目标webstie的连接已关闭而没有任何响应。

但是,如果我在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 context,Action callback)

关于这个问题的任何想法?

更新:我甚至将网站的身份验证模式设置为“无”并授权匿名用户。结果仍然相同。没有改变。问题是我可以在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
    }

0 个答案:

没有答案