在Server 2012上的身份验证中WCF服务失败但在Win7中是否正常?

时间:2014-04-11 00:24:15

标签: c# wcf authentication iis windows-server-2012

我创建了一个带有角色基础身份验证和授权的WCF服务。每个操作的实现就像

[PrincipalPermission(SecurityAction.Demand, Role = RoleConstants.Customer)]
[PrincipalPermission(SecurityAction.Demand, Role = RoleConstants.CustomerStaff)]
public void DoSomething()
{
}

成员资格提供程序和RoleManager是MySql的,而不是GAC。 SSL证书由IIS 7为https生成。

我有一些像

这样的集成测试
using (var client = new MyProxy("DefaultBinding_ILicensingService"))
{
    client.ClientCredentials.UserName.UserName = "AbcShop";
    client.ClientCredentials.UserName.Password = "tttttttt";

    client.DoSomething();
}

一个实例在Win7的dev机器上运行,另一个在Server 2012的测试服务器上运行.WCF服务的两个实例都运行良好。

但是,1个月后,我发现Server 2012上的实例不再有效,并且在身份验证方面失败,并显示以下消息。

更新

System.ServiceModel.Security.MessageSecurityException : An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
---- System.ServiceModel.FaultException : An error occurred when verifying security for the message.
Stack Trace:

Server stack trace: 
   at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
   at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

更新

我观察到以下情况并排除了一些可能的原因。

  1. 两台计算机上的auth数据库是相同的,我可以看到WCF服务在客户端发出请求后进行SQL查询以检索成员信息。
  2. 我比较了两台机器上的IIS绑定和设置,以及web.config,除了一些地址外基本相同。
  3. 事件查看器不显示有关WCF服务的警告。
  4. WCF服务实现由以下属性修饰:public class ErrorHandlerBehaviorAttribute:Attribute,IServiceBehavior,IErrorHandler,以及所有未捕获的异常将转到此属性,该属性会将错误记录到日志文件中,但是,日志文件没有记录任何内容这件事。
  5. 我比较了两个实例中加载的程序集。在Windows 7中,系统程序集基本上来自Windows \ Microsoft.NET \ assembly \ GACXXX \ XXX,但是在Server 2012中,一些程序集来自Windows \ assembly \ NativeImages_v4.0.30319_64,这里有一些位于NativeImages中的程序集:

    System   
    System.Activities   
    System.Core   
    System.Data.DataSetExtensions   
    System.Drawing   
    System.Enumerics
    System.ServiceModel.Activities   
    System.WorkflowServices   
    System.XAML   
    System.ServiceModel.Web
    

    相比之下,在Win 7中,只有System来自NativeImages。我不确定程序集或本机图像的位置是否会改变行为。

    服务和客户端是使用.NET Framework 4.5上的VS 2012开发的。

    还有什么可能使Server 2012上的实例失败?

1 个答案:

答案 0 :(得分:2)

问题解决了。

原因的根源:缺少Server 2012中的ASP .NET MVC程序集。

背景是,我希望WCF服务与将来构建的MVC应用程序共享相同的auth数据库。因此成员提供者和auth管理器是来自MVC的,并且数据库是MySql,因此提供者来自与MVC耦合的开源第三方组件。

我的未捕获异常处理程序和事件查看器无法捕获有关缺少程序集的警告的原因是: 开发PC曾被喜欢GAC的先前开发人员使用。您知道GAC可能会在开发PC中造成很多问题。来自MVC 1,2和3的大量组装在GAC中。 2.与MVC交互的第三个组件有一些糟糕的编程习惯,某些地方吞下了一些关于丢失程序集的例外。

在两台计算机中逐个比较加载的程序集后,我发现Server 2012上的WCF服务实例没有WebMatrix.WebData.dll。将程序集复制到虚拟目录的bin目录后,在复制丢失的程序集后,我收到了一系列关于更多丢失程序集的错误消息。这些程序集基本上属于MVC。错误消息出现在客户端,来自HTML服务的响应,以及服务器端的事件查看器。

所以我现在确保部署脚本包含相应的程序集。

显然,在服务从auth数据库中检索成员信息之后,服务会将信息委托给MVC的其他程序集进行进一步处理,并且第三个组件以某种方式吞下了有关缺少程序集的异常。身份验证的其他部分发出了错误的信号,然后发出了关于“验证安全性......”的误导性警告信息。

课程是: 1.请勿在开发机器中使用GAC。如果你从某人那里继承了一台开发机器,那么最好还是花一些时间来解决一些本应该通过XCopy进行私有程序集的问题。 2.某些第三方组件可能对防御性编程有一些肮脏的做法。就我而言,该组件吞下了有关缺少程序集的警告。 3.在研究其他可能的原因之前,比较加载的组件会更便宜。我使用Process Explorer在w3wp.exe中列出已加载的程序集。