2

Given a Java Servlet (running on a Windows server) which creates a new process via ProcessBuilder, what are my options for having that new process run as the user who invoked the original web request to the servlet?

To clarify, what I want is that something like

ProcessBuilder pb = new ProcessBuilder("whoami");
Process p = pb.start();
// p.getOutputStream() should contain the name of the remote user,
// not the user running the app server

And the real goal is to perform some security checks (say, to see if the user if able to open a file, or view such-and-such record in an internal enterprise system).

Clearly the user will need to be authenticated somehow, either by the app server or the java code - Ideally I'd like that to be in some way that works with single sign on (i.e. without the user entering a password), and it's fine if the solution works only from Windows clients who are already logged onto a domain (though even better if that's not a restriction). I'm currently using Jetty as the app server, but switching to something else would certainly be a viable option if necessary.

(If it helps to clarify, I'm basically looking to replace a CGI script which currently uses IIS's impersonation features to run in the context of the user making the request)

Matt Sheppard
  • 116,545
  • 46
  • 111
  • 131
  • http://spnego.sourceforge.net/ looks to do some of what I want, but without any mention of forking off a new process as the remote user. – Matt Sheppard Feb 23 '10 at 04:30
  • CreateProcessWithLogonW and CreateProcessWithTokenW can create the process, but both require credentials. http://www.cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1 seems to have some options for avoiding needing the credentials, each with their own drawbacks... – Matt Sheppard Feb 23 '10 at 22:57

2 Answers2

6

Project Waffle will get you (almost) there. It has SSO and impersonation implemented.

dB.
  • 4,700
  • 2
  • 46
  • 51
  • Thanks - Where does the 'almost' come in :) – Matt Sheppard Nov 16 '10 at 04:11
  • Someone has to do the work of adding the impersonation call into the security filter(s), saving the impersonation token for later reuse and impersonating in every new call. But at least it's achievable now. – dB. Dec 10 '10 at 13:25
  • Waffle 1.4 now also supports impersonation, see http://code.dblock.org/ShowPost.aspx?id=157. – dB. Jan 18 '11 at 23:51
  • It sure does, thanks to Nicolas Guillaumin from my team here at Funnelback - Thanks Nico! – Matt Sheppard Sep 21 '12 at 07:20
2

Your only option is going to be JNI, or some wrapper around JNI like JNA. You will need to call O/S APIs to change your effective credentials, which will also require the application server to run as administrator - which is itself a significant security consideration.

I don't know specifically about Windows APIs, but most O/S's have the ability for a sufficiently powerful profile (admin/root) to assume the identity of any user profile without needing the password. Otherwise, usually the only way to acquire a user profile token is to present legitimate authentication credentials for that profile.

One thing to be careful of is to ensure that you change the credentials for the thread, not the entire process.

Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
  • Thanks - As far as I've been able to find, there is not a way for administrator to become another user without credentials (CreateProcessWithLogonW and CreateProcessWithTokenW seem to be the Win32 way, and both require credentials), so I guess my question is how to arrange to have them or avoid needing them. Using JNI calls to actually fork the process is certainly an option if I can arrange everything else. – Matt Sheppard Feb 23 '10 at 22:32
  • Oh, and if the username and password were available, something like MiniRunAs would probably do the trick for me, avoiding the need for JNI - http://stackoverflow.com/questions/362198/how-can-i-create-a-new-process-with-another-user-account-on-windows/2308947#2308947 – Matt Sheppard Feb 23 '10 at 22:35