Skip to main content
1 of 2
Dominic Cronin
  • 18.5k
  • 3
  • 23
  • 74

Why does impersonation fail in the 2013 core service?

I've been modifying a local fork of the Tridion Powershell Module to work with a preview version of 2013. This is mostly a matter of fixing up the binding and endpoint to the relevant 2013 values. At the same time I have been adding support for the netTcp binding (which leads to more error information later in this question).

Prior to this modification work, I had been working with a simpler function to get a core service client in the Powershell:

$coreServiceClientPath = `
    'C:\Program Files (x86)\Tridion\bin\client\CoreService\Tridion.ContentManager.CoreService.Client.dll'

 function get-Core {
  Add-Type -assemblyName System.ServiceModel
  $binding = new-object System.ServiceModel.NetTcpBinding
  $binding.MaxBufferPoolSize = [int]::MaxValue
  $binding.MaxReceivedMessageSize = [int]::MaxValue
  $binding.ReaderQuotas.MaxArrayLength = [int]::MaxValue
  $binding.ReaderQuotas.MaxBytesPerRead = [int]::MaxValue
  $binding.ReaderQuotas.MaxNameTableCharCount = [int]::MaxValue
  $binding.ReaderQuotas.MaxStringContentLength = [int]::MaxValue
  $endpoint = new-object System.ServiceModel.EndpointAddress `
                       net.tcp://localhost:2660/CoreService/2012/netTcp
  Add-Type -Path $coreServiceClientPath
  new-object Tridion.ContentManager.CoreService.Client.SessionAwareCoreServiceClient `
     $binding,$endpoint
}

This works just fine, being very simple, however, when I came to port the module to 2013, I realised that the .Impersonate() call gives some trouble.

The function Get-TridionCoreServiceClient uses Impersonate() as follows:

$proxy = New-Object $serviceInfo.ClassName -ArgumentList $binding, $endpoint;
Write-Verbose ("Connecting to the Core Service as {0}" -f $serviceInfo.UserName);
$proxy.Impersonate($serviceInfo.UserName) #| Out-Null;

Where UserName is ([Environment]::UserDomainName + "\" + [Environment]::UserName)

This invocation works fine in 2011, and my get-core function which does not impersonate works fine, but in 2013, this approach results in an error condition. Here's the output (with some minor edits)

PS C:\Users\Administrator> Get-TridionCoreServiceClient -protocol http
Connecting to the Core Service at localhost...
 Get-TridionCoreServiceClient : The HTTP request is unauthorized with 
             client authentication scheme 'Anonymous'. The
             authentication header received from the server was 'Negotiate,NTLM'.

Microsoft.PowerShell.Commands.WriteErrorException,Get-TridionCoreServiceClient

PS C:\Users\Administrator> Get-TridionCoreServiceClient -protocol nettcp
Connecting to the Core Service at localhost...
Get-TridionCoreServiceClient : The socket connection was aborted. 
      This could be caused by an error processing your
      message or a receive timeout being exceeded by the remote host, 
      or an underlying network resource issue. Local socket
      timeout was '00:00:59.9958624'.

As you can see, the error output is different depending on the protocol you choose. For the netTcp variant, we also see the following in the Tridion Windows event log:

Stream Security is required at http://www.w3.org/2005/08/addressing/anonymous, 
but no security context was negotiated. This is likely caused by the remote 
endpoint missing a StreamSecurityBindingElement from its binding.

If I comment out the call to $proxy.Impersonate(), everything works fine. What differences are there between 2013 and 2011 that might cause the impersonation to fail like this? How should I correctly use the 2013 API?

Dominic Cronin
  • 18.5k
  • 3
  • 23
  • 74