Anonymous access + Windows Authentication

G

Guest

Hello,

I have a web app that uploads files to a file server (different box than the
web server). The application uses NT integrated authentication, but no users
should have permissions to the file server.

How can I use a fixed domain account to upload the files to the file server
while still preserving the users' Windows integrated authentication on the
web server?

Thank you,

Eric
 
J

JIMCO Software

Eric said:
Hello,

I have a web app that uploads files to a file server (different box
than the web server). The application uses NT integrated
authentication, but no users should have permissions to the file
server.

How can I use a fixed domain account to upload the files to the file
server while still preserving the users' Windows integrated
authentication on the web server?

Use P/Invoke and code-level impersonation. Search the KB for "asp.net
impersonation".

--
Jim Cheshire
JIMCO Software
http://www.jimcosoftware.com

FrontPage add-ins for FrontPage 2000 - 2003
 
G

Guest

Here's how impersonate the webapp user

try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Try impersonating the App Pool user
RevertToSelf();
// The next 3 steps are the important steps
WindowsIdentity wi = WindowsIdentity.GetCurrent();
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// Output WindowsIdentity
output.Write("--- RevertToSelf() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
// Output WindowsIdentity
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() + "<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n", "<br>"));
output.Write("</div>");
}

You can also use the LogonUser()

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
/// <summary>
/// This will impersonate a user using the LogonUser() and return a handle
/// to the WindowsImpersonationContext
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <param name="domain"></param>
public WindowsImpersonationContext ImpersonateUser(string login, string
password, string domain)
{
// constants used by LogonUser() method
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// handle returned from the LogonUser() method
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
// try to login to the domain
bool logonUser = LogonUser(login, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
// login unsuccessful
if(!logonUser)
{
// get the error
int lastWin32Error = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateUser failed<br>Win32Error: " +
lastWin32Error);
}
// create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
WindowsIdentity wi
= new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
// return the WindowsImpersonationContext
return wic;
}
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
protected override void RenderWebPart(HtmlTextWriter output)
{
// start of try block
try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate a user
WindowsImpersonationContext wic
= ImpersonateUser("username", "password", "domain");
// Output WindowsIdentity
output.Write("--- ImpersonateUser() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Undo the impersonation and set the CurrentPrincipal back
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
// Impersonate back to original identity
currentIdentity.Impersonate();
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() + "<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n", "<br>"));
output.Write("</div>");
}
}
 
G

Guest

Thank you for the reply, Kevin. LogonUser looks like what I'm looking for
(supplying my own username/password for the impersonation), but do you know
of a managed equivalent?

Thanks,

Eric


Kevin Schlegelmilch said:
Here's how impersonate the webapp user

try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Try impersonating the App Pool user
RevertToSelf();
// The next 3 steps are the important steps
WindowsIdentity wi = WindowsIdentity.GetCurrent();
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// Output WindowsIdentity
output.Write("--- RevertToSelf() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
// Output WindowsIdentity
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() + "<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n", "<br>"));
output.Write("</div>");
}

You can also use the LogonUser()

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
/// <summary>
/// This will impersonate a user using the LogonUser() and return a handle
/// to the WindowsImpersonationContext
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <param name="domain"></param>
public WindowsImpersonationContext ImpersonateUser(string login, string
password, string domain)
{
// constants used by LogonUser() method
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// handle returned from the LogonUser() method
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
// try to login to the domain
bool logonUser = LogonUser(login, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
// login unsuccessful
if(!logonUser)
{
// get the error
int lastWin32Error = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateUser failed<br>Win32Error: " +
lastWin32Error);
}
// create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
WindowsIdentity wi
= new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
// return the WindowsImpersonationContext
return wic;
}
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
protected override void RenderWebPart(HtmlTextWriter output)
{
// start of try block
try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate a user
WindowsImpersonationContext wic
= ImpersonateUser("username", "password", "domain");
// Output WindowsIdentity
output.Write("--- ImpersonateUser() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Undo the impersonation and set the CurrentPrincipal back
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
// Impersonate back to original identity
currentIdentity.Impersonate();
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() + "<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n", "<br>"));
output.Write("</div>");
}
}

Eric said:
Hello,

I have a web app that uploads files to a file server (different box than the
web server). The application uses NT integrated authentication, but no users
should have permissions to the file server.

How can I use a fixed domain account to upload the files to the file server
while still preserving the users' Windows integrated authentication on the
web server?

Thank you,

Eric
 
G

Guest

Eric,

Sorry ... not sure what you mean... I just tried this and it worked fine for
me:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

using System.Xml;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Threading;
using System.Security.Permissions;

namespace ScreenScrape
{

/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{

protected System.Web.UI.WebControls.Literal myPage;

private void Page_Load(object sender, System.EventArgs e)
{
RenderHtml(Response);
}

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);

/// <summary>
/// This will impersonate a user using the LogonUser() and return a handle
/// to the WindowsImpersonationContext
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <param name="domain"></param>
public WindowsImpersonationContext ImpersonateUser(string login, string
password, string domain)
{
// constants used by LogonUser() method
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// handle returned from the LogonUser() method
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
// try to login to the domain
bool logonUser = LogonUser(login, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
// login unsuccessful
if(!logonUser)
{
// get the error
int lastWin32Error = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateUser failed<br>Win32Error: " +
lastWin32Error);
}
// create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
WindowsIdentity wi
= new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
// return the WindowsImpersonationContext
return wic;
}
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
public void RenderHtml(HttpResponse output)
{
// start of try block
try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate a user
WindowsImpersonationContext wic
= ImpersonateUser("username", "password", "domain");
// Output WindowsIdentity
output.Write("--- ImpersonateUser() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Undo the impersonation and set the CurrentPrincipal back
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
// Impersonate back to original identity
currentIdentity.Impersonate();
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() +
"<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n",
"<br>"));
output.Write("</div>");
}
}


#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

}

}
 
J

JIMCO Software

Eric said:
Thank you for the reply, Kevin. LogonUser looks like what I'm
looking for (supplying my own username/password for the
impersonation), but do you know of a managed equivalent?

A managed equivalent is just going to call LogonUser just like you are. If
you really need a managed equivalent, build a managed wrapper class around
the LogonUser API and you'll have one. ;)

--
Jim Cheshire
JIMCO Software
http://www.jimcosoftware.com

FrontPage add-ins for FrontPage 2000 - 2003
 
G

Guest

Ah hah...point taken, Jim. Thank you both for your responses. You've helped
greatly! I tested the code, and it works perfectly for what I need.

Take care,

Eric
 
J

JIMCO Software

Eric said:
Ah hah...point taken, Jim. Thank you both for your responses.
You've helped greatly! I tested the code, and it works perfectly for
what I need.

I meant that to be funny, not as a sarcastic remark. :)

--
Jim Cheshire
JIMCO Software
http://www.jimcosoftware.com

FrontPage add-ins for FrontPage 2000 - 2003
 
G

Guest

I meant that to be funny, not as a sarcastic remark. :)

No worries, that's exactly how I took it.

Eric
 
G

Guest

Yeah, it was just some code I put into a Page for a paper I wrote on
SharePoint Services WebPart development describing what you would need to
impersonate another domain user ... never wrote a wrapper class around it,
which is easily done by just moving it into a class with 2 methods.
Basically just need an Impersonate() method and an Undo() method.
 
G

Guest

Is this what you need?

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;

namespace Impersonate
{
/// <summary>
/// Summary description for ImpersonateUser.
/// </summary>
public class ImpersonateUser
{

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);

private WindowsImpersonationContext wic = null;
private WindowsIdentity currentIdentity = null;

public ImpersonateUser()
{
// Get current Identity
currentIdentity = WindowsIdentity.GetCurrent();
}

/// <summary>
/// This will impersonate a user using the LogonUser() and return a handle
/// to the WindowsImpersonationContext
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <param name="domain"></param>
public WindowsImpersonationContext Impersonate(string login, string
password, string domain)
{
// constants used by LogonUser() method
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// handle returned from the LogonUser() method
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
// try to login to the domain
bool logonUser = LogonUser(login, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
// login unsuccessful
if(!logonUser)
{
// get the error
int lastWin32Error = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateUser failed<br>Win32Error: " +
lastWin32Error);
}
// create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
WindowsIdentity wi
= new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
// return the WindowsImpersonationContext
return wic;
}

public void Undo()
{
// Impersonate back to original identity
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
}

}

}
 
P

pramod

Hi Kevin,
Could you please help with this. I implemented as what you gave for
impersonation. Its working very well but what i need is cross domain
impersonation. If i use LogonUser im unable to impersonate . Im getting this
error regardless of any parameter i change for LogonUser() method

Error :

LogonUser() failed with error code: 1326

code snippet :

int bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50,
out pExistingTokenHandle);


Logonuser is only working for those user which are in same domain . How i
can implment to work with cross domain user impersonation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top