Impersonation and potential Kerberos Double-Hop in Dotnet Core API

820 views Asked by At

I'm trying to get an API to pass client credentials through to the database (on a different server) but experiencing something that smells very much like a Kerberos double-hop issue to me, however the systems people say that Kerberos delegation is set up appropriately on the servers in question. Below is a method I wrote to test this, and at the bottom is the response body I get in Postman when sending my own credentials to the API via NTLM. I get a similar response when shipping the credentials of another account I have access to. When shipping credentials I know to be bad, IIS stops my request & responds with a 401 without sending the request to the API; this is expected and required.

What can be causing this other than a Kerberos double-hop? Is there a flaw in my implementation of impersonation? I don't have access to either server in question, but I can supply the entire ugly exception encountered by the controller if needed.

/// <summary>
/// This endpoint should not support PUT.  This method is simply a means by which to test impersonation
/// </summary>
[HttpPut]
public IActionResult PutMethod()
{
    var bogusPutResult = new ImpersonationResult();
    if (!(this.User.Identity is WindowsIdentity user)) return Problem("Cannot authenticate user");

    var row1 = _myDbContext.MyTable.Find(1);
    bogusPutResult.BeforeImpersonation = $"{WindowsIdentity.GetCurrent().Name} got a row with value {row1.Value}";

    WindowsIdentity.RunImpersonated(user.AccessToken, () =>
    {
        string message;
        try
        {
            var row2 = _myDbContext.MyTable.Find(2);  // All domain users have SELECT access
            message = $" got a row with value {row2.Value}";
        }
        catch (Exception e)
        {
            message = $" ate this: {e.GetType()}--{e.Message}";
        }
                
        bogusPutResult.DuringImpersonation = $"{WindowsIdentity.GetCurrent().Name} {message}";
    });

   bogusPutResult.AfterImpersonation = WindowsIdentity.GetCurrent().Name;

   return Ok(bogusPutResult);
}

And the JSON returned by the API...

{
    "BeforeImpersonation": "MYDOMAIN\\srv-apiserviceaccount got a row with value 34 ",
    "DuringImpersonation": "MYDOMAIN\\finglixon  ate this: Microsoft.Data.SqlClient.SqlException--Login failed for user 'NT AUTHORITY\\ANONYMOUS LOGON'.",
    "AfterImpersonation": "MYDOMAIN\\srv-apiserviceaccount"
}
0

There are 0 answers