我正在尝试使用新的WCF服务。该服务在分层安全性之前正在运行。现在我收到了这个错误:
An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
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.Dispatcher.RequestChannelBinder.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)
at MyProject.IntegrationSample.MyProjectService.IMyProjectService.GetData(Int32 value)
at MyProject.IntegrationSample.MyProjectService.MyProjectServiceClient.GetData(Int32 value) in C:\code\AdvancedFraudSolutions\MyProject4.0\MyProject.IntegrationSample\Service References\MyProjectService\Reference.cs:line 82
at MyProject.IntegrationSample.Program.Main(String[] args) in C:\code\AdvancedFraudSolutions\MyProject4.0\MyProject.IntegrationSample\Program.cs:line 22
At least one security token in the message could not be validated.
这在跟踪日志中:
Message security verification failed.
这是我的服务配置:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicBinding">
<security mode="TransportWithMessageCredential"/>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MyProject.IntegrationServices.MyProjectService" behaviorConfiguration="basicServiceBehavior">
<endpoint binding="basicHttpBinding" bindingConfiguration="basicBinding"
name="MyProjectServiceEndpoint" contract="MyProject.IntegrationServices.IMyProjectService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="basicServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles"
roleProviderName="AspNetSqlRoleProvider" />
<serviceCredentials>
<serviceCertificate findValue="MyServiceCert" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="AspNetSqlMembershipProvider" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<diagnostics>
<messageLogging maxMessagesToLog="25000" logEntireMessage="true" logMessagesAtServiceLevel="false" logMalformedMessages="true"
logMessagesAtTransportLevel="true">
<filters>
<clear/>
</filters>
</messageLogging>
</diagnostics>
</system.serviceModel>
这是我的测试客户端代码和配置:
static void Main(string[] args)
{
MyProjectServiceClient client = new MyProjectServiceClient();
client.ClientCredentials.UserName.UserName = "theuser";
client.ClientCredentials.UserName.Password = "thepass";
try
{
string result = client.GetData(100);
client.Close();
Console.WriteLine(result);
}
catch (Exception ex)
{
client.Abort();
PrintExceptionDetail(ex);
}
Console.ReadLine();
}
private static void PrintExceptionDetail(Exception ex)
{
StringBuilder detail = new StringBuilder();
while (ex != null)
{
detail.AppendLine(ex.Message);
detail.AppendLine(ex.StackTrace);
ex = ex.InnerException;
}
Console.WriteLine(detail);
Console.Write("Copy exception detail to clipboard? (y/n) ");
if (Console.ReadLine().ToLower() == "y")
{
Clipboard.SetText(detail.ToString());
}
}
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyProjectServiceEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost:44306/MyProjectService.svc" binding="basicHttpBinding" bindingConfiguration="MyProjectServiceEndpoint"
contract="MyProjectService.IMyProjectService" name="MyProjectServiceEndpoint"/>
</client>
</system.serviceModel>
您可以看到我正在尝试使用basicHttpBinding,TransportWithMessageCredential安全性以及成员资格/角色提供程序进行身份验证/授权。
这是使用IIS express开发的,将在IIS中托管。
错误的原因是什么?
答案 0 :(得分:6)
我通过在服务主机web.config文件中添加计算机密钥来解决此问题。
服务跟踪日志没有帮助。它只给了我“消息安全验证失败”。然后,我使用
为服务主机web.config文件启用了wcf服务事件日志 <configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system>
</configuration>
我在计算机应用程序事件日志中得到了以下信息,这有助于
事件类型:错误 事件源:ServiceModel Audit 4.0.0.0 事件类别:MessageAuthentication 活动编号:4 日期:2013年1月30日 时间:下午3:18:27 用户:N / A. 电脑:CENTDAUD05109DL 描述: 邮件验证失败。 服务:: // mymachine:44304 / UploadService.svc 行动:http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT CLIENTIDENTITY: ActivityId:cf20ce8b-2e8c-45b5-9ab6-adc5051080f8 ProviderException:您必须指定非自动生成的计算机密钥才能以加密格式存储密码。指定不同的passwordFormat,或更改machineKey配置以使用非自动生成的解密密钥。
然后我将机器密钥添加到服务主机web.config并且它工作正常。下面是示例机器密钥。
<machineKey
validationKey=
"5AD524EF7BEB32A479F8095F8BF7653680066ADE66B5C78F80C3DC1F90
AA3D766F2B69304BFF88DEABEDE1E66D463C81FDEE0FC1A391AD90A6FD1294E7D243B1"
decryptionKey=
"0D7AE7BC7581976D76AC1D68C71BCBA978895CB792DC4F7B9F0D67774378A351"
validation="SHA1"
decryption="AES"/>
参考,
http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/
答案 1 :(得分:1)
我的配置没有任何问题。最后问题是我使用sqlserver express的UserInstance作为成员资格和角色数据库。一旦我正常创建数据库,一切都开始工作了。跛。
答案 2 :(得分:1)
我将系统时间更改为服务器时间。现在它的工作正常。但这不是一个好方法,如果用户来自其他国家,那么他们必须改变服务器时间。所以请任何人建议任何好的方法来做到这一点..
答案 3 :(得分:0)
这很可能是由于客户端和服务器之间的时间关闭。我相信默认是5分钟。您可以通过创建自定义绑定来更改最大时间偏差,也可以只验证时间是否正确。