Skip to content

WindowsIdentity.RunImpersonated sending wrong credentials #38414

@koikin

Description

@koikin

Hi all!
I'm using windows authentication to impersonate my request to the api like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddHttpClient<ApiRequests>(c =>
    {
        c.BaseAddress = new Uri(Configuration.GetSection("ApiUrl").Value);
        c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
        c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
    })
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        return new HttpClientHandler()
        {
            UseDefaultCredentials = true
        };
    });

    services.AddHttpContextAccessor();
    services.AddAuthentication();
}

On the API side I just get the identity with HttpContextAccessor.

public int GetUser()
{
    return _context.User.SingleOrDefault(e => e.Name == _httpContextAccessor.HttpContext.User.Identity.Name);
}

This works fine as long as only one user is signed in and makes the calls to the API.
But when two users are making calls.
User 1 is sometime receive user 1 data and sometime user 2 data same with User 2.
Debugging inside RunImpersonated with WindowsIdentity.GetCurrent() shows always the correct user.
But the API is not always receiving the correct user.

public async Task<User> GetUser()
{
    return await WindowsIdentity.RunImpersonated(_identity.AccessToken, async () =>
    {
        var user = new User();
        string url = "api/User";
    
        var response = await client.GetAsync(url);
        if (response.IsSuccessStatusCode)
        {
            string responseStream = await response.Content.ReadAsStringAsync();
            user = JsonConvert.DeserializeObject<User>(responseStream);
        }
        return user;
    });
}

Creating and disposing HttpClient for each api call works as expected but not recommended.

using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
    client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");

    var response = await client.GetAsync(url);
    if (response.IsSuccessStatusCode)
    {
        string responseStream = await response.Content.ReadAsStringAsync();
        user = JsonConvert.DeserializeObject<User>(responseStream);
    }
};

I'm running the api and blazor web on the same server but on different app pool.
Both are using .NetCore 3.1
Is this a bug or am I doing it the wrong way?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions