Groups | Blog | Home
all groups > dotnet remoting > july 2006 >

dotnet remoting : Using Kerberos delegation with TcpChannels


vtjdailey NO[at]SPAM gmail.com
7/3/2006 7:10:58 AM
Hello,

I am trying to have a remoting application use Kerberos authentication
because I have an application where the remoting server may make
further calls to other remoting servers, and even 3 levels deep I want
the code to run in the context of the original authenticated user.

But I can't seem to find a way to make this work. The security event
log indicates that NTLM authentication is being used, and so by the
third hop I'm just running as "Network Service".

Is this even possible with running a remoting server as a Windows
Service? Or is the only way to run a real remoting server through IIS?

Thanks for any help,

-John
vtjdailey
7/3/2006 2:19:00 PM
Here is some further information about the problem:

I figured out that I needed to set a servicePrincipalName parameter on
the channel. However I can't seem to set this property dynamically
based on which server I'm accessing:

The following code works:

System.Collections.Hashtable dict = new
System.Collections.Hashtable();
dict.Add("secure", true);
dict.Add("username", XX);
dict.Add("password", XX);
dict.Add("domain", XX);
dict.Add("connectionTimeout", 7000);
dict.Add("timeout", 30000);
dict.Add("tokenImpersonationLevel",
System.Security.Principal.TokenImpersonationLevel.Delegation);
dict.Add("servicePrincipalName",
"ServiceName/machine1:9000");

TcpClientChannel clientChannel = new TcpClientChannel(dict,
null);
ChannelServices.RegisterChannel(clientChannel, true);

In this case, the event log tells me that the user was authenticated
with Kerberos.
But I won't always be connecting to 'machine1'. I would rather do
something like this:

Configure as above, except without the
dict.Add("servicePrincipalName"....)

IDictionary dict =
ChannelServices.GetChannelSinkProperties(myProxy);
dict["servicePrincipalName"] = "ServiceName/machine2:9000";

myProxy.DoSomething();

Doesn't work -- the event log says NTLM authentication is happening,
and so delegation isn't working.

I've seen example code doing something like this with other properties,
but it seems to have no effect with this property. Running in the
debugger shows that the returned IDictionary does not have an entry
under the key "servicePrincipalName". In fact, even if I've configured
"servicePrincipalName" in advance (my first example) it still won't
appear in the IDictionary pulled from
ChannelServices.GetChannelSinkProperties(..).


So I'm at a loss as to where to go from here. I need kerberos
authentication which requires the servicePrincipalName configuration
item. And I need to reset that configuration item depending on which
remoting server I connect to.

-John
Dave Sexton
7/4/2006 5:07:56 PM
Hi vtjdaily,

TcpChannel is shared by all objects hosted on the same server, so unless
your application can handle a global change to the servicePrincipalName of a
particular TcpChannel, Remoting will not meet the needs of your app. In
other words, if your client application establishes multiple connections
asynchronously you will not be able to change the servicePrincipalName using
a single channel, and I don't think that Remoting provides a way of
requiring that a client object must use a particular TcpClientChannel.

If your app needs to establish synchronous connections try unregistering the
channel and then registering again with the required servicePrincipalName
before attempting to connect. A global variable to reference the channel
when it's created is required:

// Unregister the TcpChannel.
// 'channel' is a global variable.
ChannelServices.UnregisterChannel(channel);

// Call a method that registers the channel with the new
servicePrincipalName.
// 'channel' must be set in the RegisterChannel method.
RegisterChannel(servicePrincipalName);

HTH

[quoted text, click to view]

vtjdailey
7/6/2006 12:36:28 PM
Thanks,

I ended up using a custom sink to pass the username/password through
the message context and re-impersonating autmatically rather than
depending on the Remoting objects to do it for me.

It seems to be working now.

-John

[quoted text, click to view]
AddThis Social Bookmark Button