WCF Security Issue

Discussion in 'ASP .Net Security' started by Rafia Tapia, May 9, 2009.

  1. Rafia Tapia

    Rafia Tapia Guest

    I have written a WCF service that is hosted in a console application. The
    client is a asp.net application. I am exposing two endpoint, one is using
    wshttpbinding and other is using nettcpbinding. Both are listening on
    different ports and have the defualt bindings. So my understanding is that
    with wshttpbinding, I will get message security and with tcp I would get
    transport securtiy. My code works fine when both the client and server are
    run on the same machine but when the client is running on a remote machine
    it gives me the following error

    "The caller was not authenticated by the service. "

    Below is the app.config of the host running the service

    <system.serviceModel>
    <bindings>
    <wsHttpBinding>
    <binding name="BasicHttpBinding">
    <security mode="Message">
    <transport clientCredentialType="Basic" />
    </security>
    </binding>
    </wsHttpBinding>
    </bindings>
    <services>
    <service behaviorConfiguration="MyService1Behavior"
    name="ObjRetrievalService">
    <endpoint address="ServiceViaWindowAuthHttp" binding="wsHttpBinding"
    name="HttpWindowAuthSPObjRetrieval" contract="IObjRetrievalService"
    listenUriMode="Explicit"></endpoint>
    <endpoint address="ServiceViaWindowAuthTcp" binding="netTcpBinding"
    name="TCPWindowAuthSPObjRetrieval" contract="IObjRetrievalService" />
    <endpoint address="ServiceViaBasicAuthHttp" binding="wsHttpBinding"
    bindingConfiguration="BasicHttpBinding" name="HttpBasicAuthSPObjRetrieval"
    contract="IObjRetrievalService" />
    <host>
    <baseAddresses>
    <add baseAddress="http://my-server:11021" />
    <add baseAddress="net.tcp://my-server:11052" />
    </baseAddresses>
    </host>
    </service>
    </services>
    <behaviors>
    <serviceBehaviors>
    <behavior name="MyService1Behavior">
    <serviceMetadata httpGetEnabled="True"/>
    <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    </system.serviceModel>

    Below is the client code

    WSHttpBinding bindingElement = new WSHttpBinding(SecurityMode.Message);
    proxy = new ObjRetrievalServiceClient(bindingElement, new
    EndpointAddress(UriAddress)));

    What I want is that if on the login screen the user indicate that his
    current login credentials should be use then he does not need to supply
    username and password and in that scenario the first endpoint( on the server
    config) will be used but if the user indicate userid/password on the login
    form then the client app should communicate with the server by using the
    third endpoint(server config). Since this application will be running in our
    intranet, it makes sense to do a single sign on and the identity associated
    with window login should be use for service authentication.
    Can please help me and point me in some direction of what I am doing wrong.
    Rafia Tapia, May 9, 2009
    #1
    1. Advertising

  2. Rafia Tapia

    Steven Cheng Guest

    Hi Rafia,

    From your description, I understand that you're encountering some problem
    with WCF application that will authenticate the user via windows
    authentication, correct?

    Based on the service configuration and problem scenario you described. Here
    are something I'd like to confirm with you:

    ** Is your WCF service (in the intranet environment) designed to use domain
    account for remote client-server authentication?

    ** Are both of netTcp and wsHttpBinding required to be used in your service
    or they are involved just because you want to utilize both message layer
    and transport layer security?


    As far as I know, both wsHttpbinding and netTcpBinding support message
    layer and transport layer security(you can and you're recommended to
    explicitly configure them to use a definite security mode). Therefore, for
    your scenaro here, I think you can consider the following service design
    and configuration:

    ** just use wsHttpBinding or netTcpBinding(only one of them) and configure
    the binding to use "Message" security with "Windows" client credential
    type.

    Then, for your WCF client, you can use the current logon user's credential
    or explicitly generate a network credential via username&password(depend on
    the user selection).

    for example, here is a test service I've used on my side(the app.config
    configuration):

    ===========service app.config==========
    <configuration>
    <system.serviceModel>
    <behaviors>
    <serviceBehaviors>
    <behavior name="ServiceApp.HelloWorldServiceBehavior">
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <services>
    <service
    behaviorConfiguration="ServiceApp.HelloWorldServiceBehavior"
    name="ServiceApp.HelloWorldService">
    <endpoint address="Default" binding="wsHttpBinding"
    contract="ServiceApp.IHelloWorldService">
    <identity>
    <dns value="localhost" />
    </identity>
    </endpoint>

    <host>
    <baseAddresses>
    <add
    baseAddress="http://localhost:8731/HelloWorldService/" />
    </baseAddresses>
    </host>
    </service>
    </services>

    <bindings>
    <wsHttpBinding>
    <binding name="messageLayerWSBinding" >
    <security mode="Message" >
    <message clientCredentialType="Windows"/>
    </security>
    </binding>
    </wsHttpBinding>
    </bindings>
    </system.serviceModel>
    </configuration>
    ================================

    and the following client code invoke the service and supply the client
    windows crediential diferently according to the user selection

    #explicitly generate a NetworkCredential depend on whether current
    credential will be used or not.
    =======client -side code for invoking=========
    private void btnInvoke_Click(object sender, EventArgs e)
    {
    HelloWorldSVC.HelloWorldServiceClient client = new
    HelloWorldSVC.HelloWorldServiceClient();

    if (chkUseCurrent.Checked)
    {
    client.ClientCredentials.Windows.ClientCredential =
    CredentialCache.DefaultNetworkCredentials;
    }
    else
    {
    client.ClientCredentials.Windows.ClientCredential = new
    NetworkCredential(txtUsername.Text, txtPassword.Text);
    }

    try
    {
    string ret = client.HelloWorld();
    MessageBox.Show(ret);
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }

    client.Close();
    }
    =============================

    And here is a MSDN reference sample on how to use message layer with
    windows credentials.

    #Message Security with a Windows Client
    http://msdn.microsoft.com/en-us/library/ms729709.aspx

    If necessary, I can send you the entire test solution package. If you have
    any specifc questions, please feel free to post here.

    Sincerely,

    Steven Cheng

    Microsoft MSDN Online Support Lead


    Delighting our customers is our #1 priority. We welcome your comments and
    suggestions about how we can improve the support we provide to you. Please
    feel free to let my manager know what you think of the level of service
    provided. You can send feedback directly to my manager at:
    .

    ==================================================
    Get notification to my posts through email? Please refer to
    http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

    Note: MSDN Managed Newsgroup support offering is for non-urgent issues
    where an initial response from the community or a Microsoft Support
    Engineer within 2 business day is acceptable. Please note that each follow
    up response may take approximately 2 business days as the support
    professional working with you may need further investigation to reach the
    most efficient resolution. The offering is not appropriate for situations
    that require urgent, real-time or phone-based interactions. Issues of this
    nature are best handled working with a dedicated Microsoft Support Engineer
    by contacting Microsoft Customer Support Services (CSS) at
    http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
    ==================================================
    This posting is provided "AS IS" with no warranties, and confers no rights.

    --------------------
    >From: "Rafia Tapia" <>
    >Subject: WCF Security Issue
    >Date: Fri, 8 May 2009 19:41:26 -0400


    >
    >I have written a WCF service that is hosted in a console application. The
    >client is a asp.net application. I am exposing two endpoint, one is using
    >wshttpbinding and other is using nettcpbinding. Both are listening on
    >different ports and have the defualt bindings. So my understanding is that
    >with wshttpbinding, I will get message security and with tcp I would get
    >transport securtiy. My code works fine when both the client and server are
    >run on the same machine but when the client is running on a remote machine
    >it gives me the following error
    >
    >"The caller was not authenticated by the service. "
    >
    >Below is the app.config of the host running the service
    >
    ><system.serviceModel>
    > <bindings>
    > <wsHttpBinding>
    > <binding name="BasicHttpBinding">
    > <security mode="Message">
    > <transport clientCredentialType="Basic" />
    > </security>
    > </binding>
    > </wsHttpBinding>
    > </bindings>
    > <services>
    > <service behaviorConfiguration="MyService1Behavior"
    >name="ObjRetrievalService">
    > <endpoint address="ServiceViaWindowAuthHttp" binding="wsHttpBinding"
    >name="HttpWindowAuthSPObjRetrieval" contract="IObjRetrievalService"
    >listenUriMode="Explicit"></endpoint>
    > <endpoint address="ServiceViaWindowAuthTcp"

    binding="netTcpBinding"
    >name="TCPWindowAuthSPObjRetrieval" contract="IObjRetrievalService" />
    > <endpoint address="ServiceViaBasicAuthHttp" binding="wsHttpBinding"
    >bindingConfiguration="BasicHttpBinding" name="HttpBasicAuthSPObjRetrieval"
    >contract="IObjRetrievalService" />
    > <host>
    > <baseAddresses>
    > <add baseAddress="http://my-server:11021" />
    > <add baseAddress="net.tcp://my-server:11052" />
    > </baseAddresses>
    > </host>
    > <
    Steven Cheng, May 11, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Simon
    Replies:
    0
    Views:
    1,009
    Simon
    Oct 13, 2009
  2. Cindy Lee
    Replies:
    1
    Views:
    2,108
    Mr. Arnold
    Mar 19, 2010
  3. Robert May

    WCF Security Question

    Robert May, Mar 14, 2007, in forum: ASP .Net Security
    Replies:
    1
    Views:
    134
    Dominick Baier
    Mar 14, 2007
  4. Sarasam

    how to implement WCF Security using custom token

    Sarasam, Apr 18, 2008, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    258
    Sarasam
    Apr 18, 2008
  5. sonicm

    WCF - How much security is needed?

    sonicm, May 2, 2008, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    173
    sonicm
    May 2, 2008
Loading...

Share This Page