locked
Message level security in WCF RRS feed

  • Question

  • Hi,

    As per as my knowledge, WCF by default, Encrypts and Signs all messages for "wsHTTPBinding". Then what is the actual need of Message level security in WCF for "wsHTTPBinding"? Also, How  can I selectively define which operations can be executed by authenticated client  using Message level security?

    Thanks in advance.

    Regards

    ronit_rc



    • Edited by ronit_rc Wednesday, January 18, 2012 11:53 AM
    Wednesday, January 18, 2012 10:47 AM

All replies

  • Hello, WSHttpBinding encrypts and signs messages because it uses message security. The encryption and signing of messages are features provided by message security.

    The second question seems to be an authorization problem instead of authentication problem. This is not covered by message security. In the simplest form, you can use role based authorization as described in http://msdn.microsoft.com/en-us/library/ms731200.aspx. For advanced uses, it is recommended to use WIF. Refer to http://msdn.microsoft.com/en-us/identitytrainingcourse_webservicesandidentitylab2010_topic2 for a tutorial.


    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.
    Thursday, January 19, 2012 1:32 AM
  • HI,

    Thanks for the answer.

    So, since WSHttpBinding  uses message security and it encrypts and signs messages by default, are we required to do anything addtional, in order to implement Message level security for a wsHTTP binded WCF application?

    Also, in that case, since Message level security has been implemented by default for "wsHttpbinding", are we required to implement Transport level security for the same?

    Thanks in advance.

    Regards

    ronit_rc

    Thursday, January 19, 2012 4:37 AM
  • If you use WSHttpBinding, you don't need to do anything to enable message security. But you can configure the message security properties, such as authentication mode, or turn it off. Transport security is optional. Use it if you need SSL.
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.
    Thursday, January 19, 2012 5:24 AM
  •  

    Hi ,

    Thanks for the answer. I have one more query:

    It is understood that if, I have a WCF  service with "wsHttpBinding", by default messages are signed and encrypted. Now if I use "protectionlevel" to "Sign" for any of it's method, does it override the default behaviour and make the relevant message the operation as "Sign" only?

    Thanks in advance.

    Regards

    ronit_rc

    Thursday, January 19, 2012 8:16 AM
  • Yes. ProtectionLevel overrides the default value.
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.
    Thursday, January 19, 2012 8:37 AM
  • Hi,

    Thanks for the answer.One more query:

    While I am creating the proxy using "Add Service Reference" the encrypted messages are decrypted automatically. Where from the client is getting the decryption logic in order to decrypt a encrypted  message?

    Regards

    ronit_rc

    Thursday, January 19, 2012 9:14 AM
  • The message is encrypted or decrypted in the WCF channel (Security channel). The effect of this is that messages stay encrypted until the eventual destination is reached. Intermediraries do not see decrypted content...
    Thursday, January 19, 2012 1:52 PM
  • Hi,

    Can I implement message level security with "basicHttpbinding" binding in WCF? If supports then does it catagorically support message clientCredentialType as "UserName" ?

    Also, I have tried to implement Message level security with message clientCredentialType="UserName" in a WCF service application exposed with "wsHttpBinding". I have derived a class from class that derives from UserNamePasswordValidator and implemented the custom authentication logic by overriding the Validate method. Then I am using the class for Authentication purpose in the <serviceCredentials> section.

    My config file entries are as following:

     <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
              <serviceCredentials>
                <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomAuthenticator.CustomUserNameValidator, CustomAuthenticator" />
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <wsHttpBinding>
            <binding name="wsHttpEndpointBinding">
              <security mode="Message">
                <message clientCredentialType="UserName" />
              </security>
            </binding>
          </wsHttpBinding>

    <services>
          <service name="MyWCFService.BasicService">
       
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="MyWCFService.IBasicService"/>
          </service>
           </services>

    While browsing the service, I am getting an error "The service certificate is not provided. Specify a service certificate in ServiceCredentials." Is the error i s regarding issuing a certificate in service side? I am not interested in authenticating consumers using certificate but username/password. Why it is imposing for certificate Authorization ?

    Thanks in advance.

    Regards

    ronit_rc




    • Edited by ronit_rc Friday, January 20, 2012 11:32 AM
    Friday, January 20, 2012 10:53 AM
  • Yes, you can find a sample here http://msdn.microsoft.com/en-us/library/ms751503.aspx

    But keep in mind that it will not be Basic-profile complient.


    Friday, January 20, 2012 10:59 AM
  • Hi,

    Thanks for the answer. But the example uses clientCredentialType as "certificate". I am using clientCredentialType as "UserName". So the example does not fully answers my queries.

    Also, I couldn't get the answer of the following query:

    Can I implement message level security with clientCredentialType as "UserName" for  as"basicHttpbinding" binded in WCF service?

    Thanks in advance.

    Reagards

    ronit_rc


    • Edited by ronit_rc Friday, January 20, 2012 11:59 AM
    Friday, January 20, 2012 11:47 AM
  • Ronit,

    Yes you can. Set clientCredentialType to 'UserName'. The possible configuration of the message element for the basisHttpBinding is explained here http://msdn.microsoft.com/en-us/library/ms731338.aspx

    Good luck...

    Friday, January 20, 2012 12:03 PM
  • Hi,

    Thanks for the answer! But again the example doesn't help me. I have tried myself to implement Message level security for basicHttpBinding but getting the following error:

    BasicHttp binding requires that BasicHttpBinding.Security.Message.ClientCredentialType be equivalent to the BasicHttpMessageCredentialType.Certificate credential type for secure messages. Select Transport or TransportWithMessageCredential security for UserName credentials

    My config file entires are as following:

    <basicHttpBinding>

            <binding name="basicHttpEndpointBinding">

              <security mode="Message">

                <message clientCredentialType="UserName" />

              </security>

            </binding>

          </basicHttpBinding>

    The same binding is used in a basicHttp endpoint as following:

            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpEndpointBinding" contract="MyWCFService.IBasicService"/>

    I cannot understand the reason of the error. Could you please help on this? Also, As I have informed in the earlier post, that, I am getting a "The service certificate is not provided. Specify a service certificate in ServiceCredentials." error while trying to use Message credential to "userName" for a "wsHttpBinding".
    Thanks in advance.
    Regards
    ronit_rc

    Friday, January 20, 2012 5:12 PM
  • Hi Ronit,

    Sorry for the confusion of my previous post...  By posting the possible config options of the 'message' security element I got carried away with my thoughts! The UserName option is available for configuration of 'TransportWithMessageCredentials'. So the answer to your question is 'no', you can't use message security over a basicHttpBinding with Username. If this is not sufficient, go to the wsHttpBinding, it has way more possibilities in terms of security.

    Also a side note: try to keep one question per thread on the forum. In that way, that question can be closed. Additional quenstions are best posed in a new thread.

     

    Saturday, January 21, 2012 12:22 AM
  • Hi Peter,

    I am sorry if I got deviated from the core question of the thread. My concern is to simply implement message level security with either of the bindings. As I have said in the earlier post, even it is not working for "wsHttpBinding". The error is "The service certificate is not provided. Specify a service certificate in ServiceCredentials." In the earlier post I had provided config file entries as well. Could you please tell me how to get out of the error?

    Regards

    ronit_rc


    • Edited by ronit_rc Saturday, January 21, 2012 6:58 AM
    Saturday, January 21, 2012 6:57 AM
  • Hi Ronit,

    The reason why you get the erros is because you do not point correctly to a service certificate (in the service host config file).

    There is however an easier way to set up message security with a wsHttpBinding. That way is Windows credentials. By default the wsHttpBinding is configured for message security with Windows client credentials. So if you change nothing in the default wsHttpBinding you get the latter.

    But, If Windows authenticationo is not what you want, and for example you want to swith to Username clientcredentials you are forced to configure a service certificate. The purpose of that is that a servcie can not be authenticated by Username credentials like the client.

    How to configure the wsHttpBinding for the different scenarios is explained very well in the WCF Security Guide (http://wcfsecurityguide.codeplex.com/).  I think that resource will be very helpful for you as it explains the different options and shows examples on how to configure them.

    Also check this one on MSDN: http://msdn.microsoft.com/en-us/library/ms733137.aspx
    Saturday, January 21, 2012 8:17 AM
  •  

    Hi,

    Thanks for the answer.

    As I am setting "clientCredentialType=UserName",this means that,  the comsumer of the service is getting authenticated at the service end with custom username/password credentials. If I had wanted to autheticate the same using certificate, then I would have set "clientCredentialType=certificate". Why I am being forced to use a service certificate in case of "clientCredentialType=UserName"? What is the use of it?

    Regards

    ronit_rc

    Monday, January 23, 2012 9:51 AM
  • Ronit,

    A service can provide 2 types of credential, Windows or X.509 certificate.

    When the client uses Windows credentials, so will the service.
    When the client uses third party credentials (like username/password) the service must provide a certificate as credentials. It's just a restriction of WCF...

    The service certificate is set in the 'serviceCredentials' service behavior (when using message security) or the SSL certificate is used (when using transport security).


    If this post answers your quenstion, please mark it as such. If this post is helpful, click 'Vote as helpful'.
    Monday, January 23, 2012 10:11 AM
  •  Hi Peter,

    Thanks for the answer.

    So, is there any harm, if I use a endpoint behavior  at the Client and, which will avoid Service certificate validation ? As I know, I will put my own credential logic in place, Could I use the following endpoint behavior  at the Client end in order to avoid  Service certificate validation? I can successfully call the service using the following endpoint behaviour in the client configuration:

     <endpointBehaviors>
              <behavior name="DisableServiceCertificateValidation">
                <clientCredentials>
                  <serviceCertificate>
                    <authentication certificateValidationMode="None" revocationMode="NoCheck" />
                  </serviceCertificate>
                </clientCredentials>
              </behavior>
            </endpointBehaviors>

    Regards

    ronit_rc


    • Edited by ronit_rc Monday, January 23, 2012 11:01 AM
    Monday, January 23, 2012 11:00 AM
  • If you disable certificate validation you are not protected against invalid or revoked certificates. If you do this make sure you have some credential validation in place (can be your custom implementation).
    If this post answers your quenstion, please mark it as such. If this post is helpful, click 'Vote as helpful'.
    Monday, January 23, 2012 11:25 AM
  •  

    Hi,

    I have developed a WCF service, where I have exposed two endpoints as following:

    1) BasicHttpBinding with security mode as "TransportWithMessageCredential"

    2) wsHttpBinding with security mode as "Message" .As I am using clientCredentialType="UserName", I had to provide a certificate in "ServicecetificateCredential" section. I had used Microsoft test certificate using the Makecert command.

     While consuming the service at client end, I am checking the Traffic using Fiddler. For the BasicHttp binding, since the Message is not encrypted, I can see the data in plain text as expected. While consuming the wsHttp endpoint, four calls are being made and encryption of data has happened as expected. But the data is being diaplayed in the 4th call. I cannot understand, is the data is being decrypted by the Fiddler tool and being shown as it is a test certificate. Could anybody help me on this ?

    Regards

    ronit_rc

    Wednesday, January 25, 2012 12:45 PM
  • Ronit,

    Are you absolutely sure that 4th call is not from the basicHttpbinding? The wsHttpBinding set up for Message security will not show the message body! Unless you enable Message Body loggin on the 'Service' level in WCF diagnostices.


    If this post answers your quenstion, please mark it as such. If this post is helpful, click 'Vote as helpful'.
    Thursday, January 26, 2012 6:20 PM
  • If you use WSHttpBinding, you don't need to do anything to enable message security. But you can configure the message security properties, such as authentication mode, or turn it off. Transport security is optional. Use it if you need SSL.
    reputation managemant
    Friday, January 27, 2012 6:16 AM
  •  

    Hi Peter,

    I am absolutely sure that the 4th call is not from the "basicHttpbinding"  but "wsHttpbinding". It is happening only when the same service is being exposed with two different endpoints using two different endpoint behaviours. I have tested a WCF service with a single "wsHttpbinding" endpoint and found messages in all the four calls are being encrypted. I think, the problem is happening only when we are trying to expose two different enpoints with two different endpoint behaviours developed in the context of security. I am really confused, what is happening. Could you please help me on this?

    Regards

    ronit_rc

    Friday, January 27, 2012 6:25 AM
  • Post your configuration (of both endpoints)
    If this post answers your quenstion, please mark it as such. If this post is helpful, click 'Vote as helpful'.
    Friday, January 27, 2012 6:27 AM
  •  

    Hi Peter,

    Please find the configuration:

    <?xml version="1.0"?>
    <configuration>

      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
              <serviceCredentials>
                <serviceCertificate findValue="30027c0d951ed393c51502e7aa94af5587104b88" storeLocation="LocalMachine" x509FindType="FindByThumbprint" />
                <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomAuthenticator.CustomUserNameValidator, CustomAuthenticator" />
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <wsHttpBinding>
            <binding name="wsHttpEndpointBinding">
              <security mode="Message">
                <message clientCredentialType="UserName" />
              </security>
            </binding>
          </wsHttpBinding>
          <basicHttpBinding>
            <binding name="basicHttpEndpointBinding">
              <security mode="TransportWithMessageCredential">
                <message clientCredentialType="UserName" />
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
       
        <services>
          <service name="MyWCFService.MyService">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpEndpointBinding" contract="MyWCFService.IMyService"/>
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="MyWCFService.IMyService"/>
          </service>
        </services>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
     
    </configuration>

    Regards

    ronit_rc

     

    Friday, January 27, 2012 6:36 AM
  • I can't see problems in the config...

    Don't forget that message security only encrypts the SOAP:Body (the header will be visible, by default).

    What i suggest if you don't find the cause... Remove the other endpoints, only expose the one that you need to debug, it will avoid confusion.

    Also, use WCF Tracing instead of Fiddler, it has a ton more capabilities to troubleshoot WCF problems.


    If this post answers your quenstion, please mark it as such. If this post is helpful, click 'Vote as helpful'.
    Friday, January 27, 2012 6:49 AM
  •  

    Hi Peter,

    I have already done that but no change in the behavior. The data in the message is being exposed in the 4 th call. You want me to send the HTTP trafic captured by Fiddler for each call in case of "wsHttpBinding"?

    Regards

    ronit_rc


    • Edited by ronit_rc Friday, January 27, 2012 7:47 AM
    Friday, January 27, 2012 7:46 AM