Hello

This is my first post and also my first foray into the wonderful world
of .NET Remoting.
I apologise if it's a little long.

I have been experimenting with .NET remoting particularly in the area of
authentication.
I have hosted a simple component in IIS 6 running on Windows 2003 Server
and successfully
communicated with it using Integrated Authentication from both the command
line and an ASP.NET
program. I need identity flow down and have set the relevant flags in the
config files
(Impersonate=true and usedefaultcredentials=true). I checked the security
context of the thread
the remote component and it reports the correct flowed down user.

Now I have read that Integrated Authentication is not good for general
internet usage
since it uses ports other than port 80 and in general is blocked by proxies
and firewalls.
The article I have read also suggests that Digest Authentication is more
suitable and almost as secure.
Now the fun starts - I cannot find an awful lot of documentation on Digest
and so far I have been
unable to authenticate using Digest (see dump below) remote calls from
either a command line or ASP.NET based
program.

  Unhandled Exception: System.Net.WebException: The remote server returned
an error: (401) Unauthorized.
  Server stack trace:
    at
System.Runtime.Remoting.Channels.Http.HttpClientTransportSink.ProcessRespons
eException(WebException webExcepti
  on, HttpWebResponse& response)
    at
System.Runtime.Remoting.Channels.Http.HttpClientTransportSink.ProcessMessage
(IMessage msg, ITransportHeaders r
  equestHeaders, Stream requestStream, ITransportHeaders& responseHeaders,
Stream& responseStream)
    at
System.Runtime.Remoting.Channels.SoapClientFormatterSink.SyncProcessMessage
(IMessage msg)

  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 HIS.VDSTest.TimingServer.Test(TestClass t) in
D:\Prototypes\SysArch\VCSS\VDSTest\TimingServer\TimingServer.cs:
  line 38
    at HIS.VDSTest.TimingClient.Main(String[] args) in
d:\prototypes\sysarch\vwss\vdstest\timingclient\timingclient.c
  s:line 113

So perhaps if I explain what I have done someone out there could put me on
the right track.

First of all the remote component host is IIS server 6 running on W2K3
server.
It's a vanilla install with no actual web site just a Virtual Directory
containing 'bin'
(for the remote component) and the web.config file. The config file looks
like this :-

  <configuration>
    <system.web>
      <authentication mode="Windows" />
      <identity impersonate="true" />
      <authorization>
        <allow users="DOMAIN\Username" />
        <deny users="*" />
      </authorization>
    </system.web>
    <system.runtime.remoting>
      <application>
        <service>
          <wellknown mode="SingleCall" type="HIS.VDSTest.TimingServer,
TimingServer" objectUri="TimingServer.soap" />
        </service>
      </application>
    </system.runtime.remoting>
  </configuration>


I have also set the IIS Directory security mode on the virtual directory to
use Digest Authentication,
the Realm has been set to the domain name. I have tested with anonymous
access both on and off -
no difference.

The client setup runs on a Windows 2000 Pro machine with .NET V1.1
installed and was built with
Visual Studio 2003. The initial client test program was commandline based,
but further tests were
conducted with a ASP.NET hosted client.

The client configuration code  is as below :-

  <configuration>
    <system.runtime.remoting>
      <application>
        <client url="http:/localhost/TimingClient">
          <wellknown type="HIS.VDSTest.TimingServer, TimingServer"
url="http://testlab_ts08/ComponentHost/TimingServer.soap"; />
        </client>
        <channels>
          <channel ref="http" />
          <!--<channel ref="http" useDefaultCredentials="true" />-->
        </channels>
      </application>
    </system.runtime.remoting>
  </configuration>

Initially I tested with useDefaultCredentials=true and no change to the
client software i.e. the
same combination that worked with Integrated Authentication. It failed of
course. I assume
that the default credentials for a command line program relate to
Integrated Authentication only,
I could find no .config file settings hinting at the use of Digest. I have
found an article
which details a programmatic method and I have tried this out, the code is
below.

        RemotingConfiguration.Configure("TimingClient.exe.config");

        TimingServer obj = new TimingServer();

        IDictionary channelProperties =
ChannelServices.GetChannelSinkProperties(obj);
        NetworkCredential credentials;
        credentials = new NetworkCredential("User", "password", "Domain");
        ObjRef objectReference = RemotingServices.Marshal(obj);
        Uri objectUri = new Uri(objectReference.URI);

        Console.WriteLine("Uri:" + objectUri.ToString());

        CredentialCache credCache = new CredentialCache();
        // Substitute "authenticationType" with "Negotiate", "Basic",
        // "Digest",
        // "Kerberos" or "NTLM"
        credCache.Add(objectUri, "Digest", credentials);
        channelProperties["credentials"] = credCache;
        channelProperties["preauthenticate"] = true;

        // call remote object method
        obj.Test ();

Still no joy - although the code above does work when "NTLM" is substituted
for "Digest" in the
credCache.Add(objectUri, "Digest", credentials) method and the remote IIS
host directory
security is set back to Windows Integrated.

Thinking that perhaps the client code required hosting in IIS I gave this a
try but to no avail.
The client setup here was similar to above, the client machine has IIS 6.0
installed. The client
side IIS Virtual Directory was configured to use Digest authentication (My
initial requirement).
The remoting config file was read in the global.asax startup method and a
simple page with
a button_click method calling the remote component was executed. The test
was run from both the
local browser and a browser on a different machine and domain, the usual
401 return was received
in both cases. The client side user identity was printed on the debug
console and reflected the
correct logged on user. I have not tried the programmatic method shown
above within the IIS
client yet. Windows authentication and Impersonation was turned on in the
client side web.config
file, I assume that windows authentication also covers Digest
authentication since there is no
Digest option?.

In summary.
The question is can I configure Digest Authentication for .NET Remoting/IIS
to enable user
identity flowdown to a remote component server (components hosted in IIS)
from both:

A command line (or Windows Forms) program with programatic Digest settings.
(or current logged on user context if possible).

An IIS Digest authenticated user context impersonated by a ASP.NET hosted
client.


Failing this is there any way user context can be flowed down if a Forms
based login method
is used?- say using the credential cache mechanism.

I don't want to reinvent the windows user/permission mechanism.

 Thanks in advance.
 Norman Burkies
 High Integrity Systems

Reply via email to