Remoting Security (Web Services)
A client that I am currently helping out was concerned that the web service that a previous developer had written for him had hard coded credentials for consumption, which obviously is poor since a better security practice is to retrieve credentials from the the requesting user or call the credentials from a secure source. He was wondering if indeed this was the case, and if so, what could be done to change the authentication scheme to something like NTLM authentication.
After examining the application source, I saw indeed that there was hard-coded credentials in the channel sink properties.
- IJobServer obj = (IJobServer)Activator.GetObject
- ( typeof(IJobServer),
- ["username"] = "username";
- ["password"] = "password";
- ["domain"] = "domain";
The ChannelServices class is an important remoting class because it faciliates actions such as registering listening channels. For example:
- HttpChannel myJobChannel = new HttpChannel (5000);
- ChannelServices.RegisterChannel( myJobChannel );
The GetChannelSinkProperties method is nice when you have a transparent proxy reference in order to get back an IDictionary of the relevant properties. In this case the properties that are being returned are the credential properties, but it could really be anything:
- IDictionary channelProperties =
- channelProperties["propname"] = propertyValue;
Hard-coding the values is typically an acceptable practice if you passing credentials explicitly in clear-text however are secured from an SSL pipe standpoint. However, this was not currently the case for my client.
In order to fix this so that the hardcoded authentication wasen’t being used, there were a few adjustements that had to be implemented. The first is to change the web.config file.
- <authentication mode="Windows"/>
- <identity impersonate="true"/>
Then in the code adjusting the consumed properties on the channel sink.
- IDictionary props = new Hashtable();
- props["userDefaultCredentials"] = true;
- HttpChannel channel = new HttpChannel (
- new SoapServerFormatterSinkProvider()
Using the above code in the channel constructor specifies the use of the useDefaultCredentials property which would supply the default credentials at run time. Although I choose the route of configured this property in code, it could optionally be done through the use of a configuration file as demonstrated below.
- <channel ref="http" useDefaultCredentials="true"/>
The result of both impelementations is identical, so it is a developer choice which method is most appropriate for their purpose.