ASP.NET CORE 1.0, Impersonation
Asked Answered
P

2

6

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?

Pallmall answered 3/2, 2016 at 15:18 Comment(0)
C
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.

Caracas answered 3/2, 2016 at 17:42 Comment(5)
blowdart's solution will work, I just tested it against RC1. I used an updated version of this that targeted 4.5.1: impersonation.codeplex.com which I believe originated from the same MSDN example which has been around for a while.Jannjanna
@blowdart: Is it still core even if I target only dnx-clr?Pallmall
@blowdar: Is there a beta of RC2 where I get the WindowsPrincipal?Pallmall
@Pallmall no. It's only on the nightly builds.Caracas
@Caracas Since RC2 is now released, could you update your answer?Exoenzyme
B
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(...);
    ...
}
Brassware answered 7/10, 2016 at 2:6 Comment(2)
that code beautifully fails with newest stable core mvc =(Yim
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...Brassware

© 2022 - 2024 — McMap. All rights reserved.