Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF and Multiple Security Models

We're working on a WCF service to house our core API.

We're working on 2 clients to use this API one of which is a WPF desktop app that will most likely authenticate against active directory and reside on the same domain as the API. The other is an ASP.Net web application that will most likely use ASP.Net Membership for security and still reside on the same domain as the WCF service. The plan is for the WCF service to use NetTcp and be hosted inside a Windows Service.

Where possible I would like the WCF service to run as the calling user, I guess this should be fairly straight forward for the desktop app where the user is a domain user. For the web app I guess I will need to create a user for service calls to run under.

Is it possible to get this kind of double approach to security to run over a single WCF service or will I need to make 2 services each with it's own security model?

Also if anyone has any thoughts on best practises/patterns for achieving this that would be great.

Thanks

like image 590
Gavin Avatar asked Jan 27 '26 08:01

Gavin


1 Answers

I've solved the same problem in the following way:

  1. I created two net.tcp binding for every usage.

      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="" />
        <message clientCredentialType="UserName" />
      </security>
    
    </binding>
    <binding name="WindowsBinding" >
    
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Windows" />
      </security>
    
    </binding>
    

  2. Next, I added two endpoints for every services

    <service name="SimplePluginService" behaviorConfiguration="CommonBehavior">
    
       <endpoint binding="netTcpBinding" bindingConfiguration="UserNameBinding" name="SimplePluginServiceUserName" contract="ISimplePluginService">
           <identity>
                <dns value="WCfServer" />
           </identity>
       </endpoint>
    
       <endpoint binding="netTcpBinding" bindingConfiguration="WindowsBinding" name="SimplePluginServiceWindows" contract="ISimplePluginService">
           <identity>
                <dns value="WCfServer" />
           </identity>
        </endpoint>
    
    </service>
    
  3. Next, I choosed the appropriate endpoint when I create ChannelFactory (ConnectionManager - class, which contains information about user's creditionals).

    private readonly Dictionary<Type, Object> channelFactoryDictionary = new Dictionary<Type, Object>();
    
    private ChannelFactory<T> GetChannelFactory<T>() where T : class
    {
        if (channelFactoryDictionary.Keys.Contains(typeof(T)))
        {
            return channelFactoryDictionary[typeof(T)] as ChannelFactory<T>;
        }
        else
        {
            string endpointName=typeof(T).ToString();
            if (ConnectionManager.IsWindowsAuth) endpointName+="Windows";
            else  endpointName+="UserName";
    
            ChannelFactory<T> channelFactory = new ChannelFactory<T>(endpointName);
    
            if (!ConnectionManager.IsWindowsAuth){
                 channelFactory.Credentials.UserName.UserName = ConnectionManager.Password;
                 channelFactory.Credentials.UserName.Password = ConnectionManager.Password;
            }
    
            channelFactoryDictionary.Add(typeof(T), channelFactory);
            return channelFactory;
        }
    }
    
like image 173
Sir Hally Avatar answered Jan 30 '26 07:01

Sir Hally



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!