简体   繁体   中英

WCF Error - Message security verification failed

I'm trying to get going with a new WCF service. The service was working before layering on security. Now I am getting this error:

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.

And this in the trace log:

Message security verification failed.

Here is my service configuration:

<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>

Here is my test client code and configuration:

    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>

You can see that I'm trying to use basicHttpBinding, TransportWithMessageCredential security, and Membership/Role providers for authentication/authorization.

This is being developed using IIS express and will be hosted in IIS.

What is the cause of the errors?

I resolved this issue by adding the machine key on the service host web.config file.

The service trace log didn't help. It only gave me "Message security verification failed.". Then I enabled the wcf service event log for the service host web.config file using,

 <configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="NewBehavior">
                    <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
                </behavior>
           </serviceBehaviors>
        </behaviors>
    </system>
  </configuration>

I got the following in the computer application event log which helped,

Event Type: Error Event Source: ServiceModel Audit 4.0.0.0 Event Category: MessageAuthentication Event ID: 4 Date: 30/01/2013 Time: 3:18:27 PM User: N/A Computer: CENTDAUD05109DL Description: Message authentication failed. Service: ://mymachine:44304/UploadService.svc Action: http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT ClientIdentity: ActivityId: cf20ce8b-2e8c-45b5-9ab6-adc5051080f8 ProviderException: You must specify a non-autogenerated machine key to store passwords in the encrypted format. Either specify a different passwordFormat, or change the machineKey configuration to use a non-autogenerated decryption key .

I then added the machine key to the service host web.config and it worked. Below is the sample machine key.

 <machineKey 
validationKey= 
"5AD524EF7BEB32A479F8095F8BF7653680066ADE66B5C78F80C3DC1F90
AA3D766F2B69304BFF88DEABEDE1E66D463C81FDEE0FC1A391AD90A6FD1294E7D243B1" 
decryptionKey=
 "0D7AE7BC7581976D76AC1D68C71BCBA978895CB792DC4F7B9F0D67774378A351"  
validation="SHA1" 
decryption="AES"/>

References,

http://blogs.microsoft.co.il/blogs/urig/archive/2011/01/23/wcf-quot-an-error-occurred-when-verifying-security-for-the-message-quot-and-service-security-audit.aspx

http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/

I changed my System Time to Server Time. Now its Working Fine. But it is not good method , if users are from other countries ,then they must change time to server time. so please any one suggest any good method to do this..

There was nothing wrong with my configuration. The problem ended up being that I was using a UserInstance of sqlserver express for the membership and roles database. Once I created a database normally, everything started working. Lame.

It's most likely due to the time being off between the client and server. The default I believe is 5 minutes. You can change the max time skew by creating a custom binding, or you can just verify that the times are correct.

<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />

This line really helped after days of trying to debug

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM