OWIN Web API Windows Service - Windows Identity Im

2019-04-02 02:17发布

问题:

This is an intranet app.

I have a WebAPI Owin selfhosting app running on a Windows Server under a service account.

The Front end is AngularJS which talks to the database through this Web API.

What I want is when any action is invoked on the API which requires database interaction, the user credentials are used to connect to the database, and not the service account itself.

I am using Windows authentication, and I have enabled Ntlm authentication on the httpListener in the Startup class, and I am able to authenticate the user.

When I submit a request to Web api, I can see that the Thread.CurrentPrincipal returns the current user, but the database connection fails, because it is trying to connect to the database using the service account, and not the user credentials.

Please tell me how to pass the user credentials to the database from Web API

回答1:

You should impersonate the calling user like this:

public void PerformDBOperationAsCallingUser()
{
    WindowsIdentity callingUser = (WindowsIdentity)Thread.CurrentPrincipal.Identity;

    using (WindowsImpersonationContext wic = callingUser.Impersonate())
    {
        // do your impersonated work here...
        // check your identity like this:
        var name = WindowsIdentity.GetCurrent().Name;
    }
}

Would be nice to use this piece of code as a decorator around your unit of work. But depends on the rest of your design.



回答2:

If you need to connect with the user who is logged in to your app, you can impersonate his credentials to access the database. Something like this might work.

public static void Test()
{
    WindowsIdentity ident= (WindowsIdentity)HttpContext.Current.User.Identity
    using (WindowsImpersonationContext ctx = ident.Impersonate())
    {
        using (SqlConnection con = new SqlConnection("Data Source=YourServer;Initial Catalog=YourDatabase;Persist Security Info=False;Integrated Security=SSPI"))
        {
            con.Open();
        }
        ctx.Undo();
    }
}