The ability to use NTLM/Kerberos and a secure channel in Remoting 2.0 makes this technology suddenly interesting again (for server-to-server communication).
I couldn’t find any documentation on that on MSDN – so I fired up good old Reflector to figure out the configuration settings – hope this saves you some time.
Client-Settings
- secure
true/false: enables/disables security - username, password, domain
if you don’t want to use the credentials of the client process, you can specify explicit ones here - impersonationLevel
Identification: The server can use the client token only for identity information and role based checks
Impersonation: The server can impersonate the client token to access server-local resources
Delegation: The server can delegate the client credentials - protectionLevel
None: clear text
Encrypt/Sign: self explanatory
EncryptAndSign: recommended setting - servicePrincipalName
SPN of the server. Required for Kerberos. Can use SPN (service/domain) or account syntax (domainservice)
Example:
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel
ref=“tcp“
secure=“true“
tokenImpersonationLevel=“Impersonation“
protectionLevel=“EncryptAndSign“
servicePrincipalName=“Server/Leastprivilege“ />
</channels>
</application>
</system.runtime.remoting>
</configuration>
The server supports, like ASP.NET, auto-impersonation of the client by adding a impersonate=”true” attribute to the remoting config.
<channels>
<channel ref=“tcp“ secure=“true“ port=“8080“ impersonate=“true“ />
</channels>
Two things to watch out when you enable auto-impersonation. First the server account needs the SeImpersonatePrivilege (Impersonate Client after Authentication) which can be configured in secpol.msc. In addition the client needs NTFS read ACLs on shared assemblies on the server like an interface assembly.
Also like in ASP.NET, the client identity is set on Thread.CurrentPrincipal, from where you can grab it to do role based checks, impersonate etc…
The following code shows how to figure out if you are impersonating, who your client is and in which security context the current call is executed.
void ISharedInterface.HelloWorld(string input)
{
string securityContext = WindowsIdentity.GetCurrent().Name;
string clientIdentity = Thread.CurrentPrincipal.Identity.Name;
if (WindowsIdentity.GetCurrent(true) != null)
Console.WriteLine(“Impersonating the client”);
Console.WriteLine(“Client Identity: “ + clientIdentity);
Console.WriteLine(“Security Context: “ + securityContext);
}
you can also check which authentication method has been used (this is quite handy for troubleshooting, as you need Kerberos authentication for delegation).
Console.WriteLine(“Authentication Type: {0}”,
Thread.CurrentPrincipal.Identity.AuthenticationType);