7

I'm writing an Intranet application. Target framework in project.json is dnx451. That's my publishing command:

dnu publish --runtime dnx-clr-win-x86.1.0.0-rc1-update1 --no-source

Database Connection string:

Server=name;Database=name;Trusted_Connection=True;

I'm trying to impersonate the database access but it's not working. When I start the application my windows user is recognized and it says Hello, Domain\Username on top right. As soon as I try to access the database I get the error "Login failed for user Domain\Computername". If I run the application pool under my user then everything works fine.

IIS: .NET CLR Versio is v4.0, Managed Pipline Mode Classic and Identity is ApplicationPoolIdentity. Website authentications: ASP.NET Impersonation and Windows Authentication are enabled.

What do I need to change that impersonation is finally working?

Dani
  • 971
  • 12
  • 31

2 Answers2

8

Core does not support impersonation because all web code is out of proc, hosted by Kestrel. If you want to do it you need to take the current Principal, as a WindowsPrincipal, then manually impersonate at the point where you need it.

One thing to note is that in RC1 you don't get a WindowsPrincipal, so you can't do this right now. It'll be fixed in RC2.

blowdart
  • 55,577
  • 12
  • 114
  • 149
8

If you want every page request to impersonate the user, you can configure your own Middleware to run before MVC;

public class Impersonate
{
    private readonly RequestDelegate next;
    public Impersonate(RequestDelegate next) {
        this.next = next;
    }
    public async Task Invoke(HttpContext context) {
        var winIdent = context.User.Identity as WindowsIdentity;
        if (winIdent == null) {
            await next.Invoke(context);
        }else {
            WindowsIdentity.RunImpersonated(winIdent.AccessToken, () => {
                next.Invoke(context).Wait();
            });
        }
    }
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
    ....
    app.UseMiddleware<Impersonate>();
    app.UseMvc(...);
    ...
}
Jeremy Lakeman
  • 9,515
  • 25
  • 29
  • 1
    that code beautifully fails with newest stable core mvc =( – Andrii Horda Feb 21 '17 at 14:41
  • 1
    Apologies, I had mistakenly tried to invoke the next handler asynchronously, which just meant that the impersonation probably only applied up to the first awaited I/O call. Then the async Task would be returned, RunImpersonated would return, and we'd wait for the rest of the web pipeline. Instead the impersonation must block the request thread until the next delegate has completed (as edited above?). Though there may still be async code that runs on a different thread... – Jeremy Lakeman Aug 11 '17 at 01:58