32

I'm writing some code to utilise a 3rd party component, and I need to supply an object which implements ICredentials when I start to use it.

If I write the following...

var credential = new NetworkCredential("MyUsername", "MyPassword");

...and pass "credential", it's fine. But I would like to pass the credentials of the current user (it's a Windows service, so runs as a specified user).

I have tried both of the following, but neither appear to work (or return anything):

NetworkCredential credential = System.Net.CredentialCache.DefaultCredentials;
NetworkCredential credential = CredentialCache.DefaultNetworkCredentials;

Can anyone suggest how to acquire an approriate object, which represents the credentials of the username that the service is running under ?

Thanks

Black Light
  • 2,358
  • 5
  • 27
  • 49
  • See http://stackoverflow.com/questions/3166150/how-do-i-tell-a-wcf-client-proxy-class-to-use-windows-authentication-and-the-wind You may need – Alan Christensen Jul 19 '11 at 03:29
  • I have the same problem with a WCF client scenario, see this thread http://stackoverflow.com/questions/3166150/how-do-i-tell-a-wcf-client-proxy-class-to-use-windows-authentication-and-the-wind – Mahol25 Jul 02 '10 at 15:12
  • CredentialCache should work. Can you check WindowsIdentity.GetCurrent and see there really is a user logged? – Simon Mourier Nov 19 '11 at 09:08
  • 3
    Hi, WindowsIdentity.GetCurrent returns a WindowsIdentity object (with the current username), but both System.Net.CredentialCache.DefaultCredentials and DefaultNetworkCredentials return empty ICredentials objects. – Black Light Nov 22 '11 at 15:16
  • What is your 3rd party component? Does it support things like NTLM or Kerberos? The answer isn't going to be to try and read the user's password - that'd be a glaring security hole. You need to figure out a *different* way of authenticating. – Mark Brackett Jun 08 '12 at 22:32
  • See my response to Ross Presser's proposed answer. Basically, I never suggested that I wanted to acquire the password. – Black Light Jun 13 '12 at 12:33
  • The [NetworkCredential](http://msdn.microsoft.com/en-us/library/system.net.networkcredential(v=vs.110).aspx) object is an object designed to hold username and password. If you want to pass capabilities from your app to another process, a NetworkCredential object is not going to be the way to do that. – Ross Presser Dec 03 '13 at 22:51
  • Ah... I see your point. NetworkCredential isn't some kind of security context object (the "current" instance of which might be acquired from somewhere), more a container for a username and password. Therefore some hypothetical "current" instance would have the current username and password, and hence doesn't exist. I can see why that would be the case, but a bit of a poor design (to use it) on the part of the 3rd party. Thanks again. – Black Light Dec 18 '13 at 09:12
  • @BlackLight have you found a solution on this one? – quinekxi Jun 22 '16 at 13:40

6 Answers6

2

have you tried WindowsIdentity.GetCurrent()?

you could also look at this example... http://www.codeproject.com/KB/vb/Windows_Service.aspx

yamspog
  • 18,173
  • 17
  • 63
  • 95
  • "have you tried WindowsIdentity.GetCurrent ?" Yes, it doesn't appear to help - even if you pass the result into Impersonate. The example just appeared to be an interesting (?) way to get the current username. Thanks – Black Light Apr 12 '10 at 13:23
0

Unfortunately you have to interop with the WMI like this:

http://www.codeproject.com/Articles/28161/Using-WMI-to-manipulate-services-Install-Uninstall

The value you're looking to query for is StartName, which will evaluate to something like "NT Authority\NetworkService" (or whatever you're using). If you mash up the second part of this article with the first part getting it should be pretty straightforward.

Jeff
  • 2,701
  • 2
  • 22
  • 35
0

Have you tried setting the principalpolicy for the appdomain at the start of the application?

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

Setting this value before accessing the current principal object via the thread makes sure the windows identity is used in this object.

edit - I'm pretty sure this works for DefaultNetworkCredentials. I used it to access a web service with windows authentication from a windows forms app.

stombeur
  • 2,704
  • 22
  • 45
0

You need to do impersonation, for example:

    System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = 
    ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

//Insert your code that runs under the security context of the authenticating user here.

impersonationContext.Undo();

http://support.microsoft.com/kb/306158

Or you can use web.config:

<identity impersonate="true" />
Alexan
  • 8,165
  • 14
  • 74
  • 101
  • 2
    Thanks, but I'm running as a Windows service, not as an ASP web page. All the suggestions I have so far found are ASP related. I already tried impersonation, but it doesn't help/work (in this context). I'm amazed that there appears to be no way to acquire the credentials of the current user (who is logged in after all), and have instead to code some hacky method to store the user's username and password. Yuk ! (thanks for you suggestion though) – Black Light Mar 17 '10 at 17:00
0

The ideal security situation is that the password of a logged in user is not stored anywhere in memory. It is not stored anywhere on disk either. It exists only as a hash value to be compared against a string entered by a human being. Storing a password in clear is inherently a security risk and should be avoided whenever possible.

Given this principle, there is NO part of the operating system that even HAS your user's password in the clear, much less be willing to give it to you.

Ross Presser
  • 6,027
  • 1
  • 34
  • 66
  • 5
    There seems to be some confusion here. I never asked how to acquire the password. I asked, given that I have a process which must have been "logged in" (for want of a better term), it is running about with valid credentials. I wanted to pass those to a 3rd party component - I didn't need to know what they were. I knew that it I created a new set of credentials (assuming I knew the password) it worked, but I couldn't find a way to acquire (and pass on) the *current* credentials. – Black Light Jun 13 '12 at 12:31
  • That's exactly the situation I was describing. To acquire the current credentials they would have to be HELD by some software somewhere. That would reduce the security of the system. Impersonation should allow whatever component you wish to invoke to _act_ as the logged in user without needing the actual credentials. I'm not sure why you downvoted me and not the first answer to this post, which made the same statement about security ("In fact it is an unsafe practice"). – Ross Presser Sep 02 '12 at 01:55
  • 1
    Having a signed token that represents the credentials of the current process (which are allowed to DO things, including talking to other programs as itself, as the process) is not the same as having the credentials. As there are multiple ways that a process might talk to another process, this is configurable. Passing this token as an argument is the expected way of specifying that we want to authenticate "as myself" and not using some new credentials. That's all we're trying to do. – Jason Kleban Dec 02 '13 at 19:46
  • 1
    NetworkCredential *BY DEFINITION* needs a username and password. It is conceivable that there might be a different iCredential that does not, and that you can feed to your 3rd party component. But I couldn't find one. – Ross Presser Dec 16 '13 at 18:54
-2

if you just want to run a process as the current user adds the verb: "runas " & Environment.UserName

If you want to run the process as admin just wrote "runas"

in vb.net

Dim ps As New System.Diagnostics.ProcessStartInfo("filepath", "arguments")

ps.Verb = "runas" 'run as admin

'ps.Verb = "runas " & Environment.UserName'run as current user, by default

Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(ps)

if you want to get the current user password, you can not, in fact it is an unsafe practice. What right and for what purpose your service needs to get my Windows password secret? for example is like giving the pin code of your phone to whatsapp

Croket
  • 5
  • 1