I want to let remote administrators (with local or domain credentials) control my Windows service via a WCF TCP binding. To do this, I need to authenticate the remote user as an administrator. I can check the principal user/roles, but I don't know how to prompt the remote user for the correct user details/token.
This is related to my previous question on Restricting WCF TCP endpoint to Administrators. Instead of adding [PrincipalPermission(SecurityAction.Demand, Role = "Administrator")]
to my restricted service method and catching a SecurityException
, it seems I can check for it with:
if (!System.Threading.Thread.CurrentPrincipal.IsInRole("Administrators"))
return MethodResult.AccessDenied;
// haven't tested if it's the service thread or the remote user yet.
How do I prompt the remote user for Windows authentication if a Access Denied result was returned so I can reinitiate the connection as a different principal?
Of course, the change would need to be effected on the remote user's client application. Perhaps there is a cleaner WCF way to do it?
Edit: Searching for ".net impersonation" led me to this on CodeProject. Haven't had a chance to look, but this may be the way to go.
You need to pass in the user's credentials with your WCF call. Normally the client application just "captures" the currently running user's credentials. Alternatively you can specify a username and password explicitly. So you could prompt the user for an alternative set of credentials if you wish.
Either way, the client app needs to prompt the user. Your WCF call should return an error (code or exception) upon authorization failure and your client should capture that return and display a prompt to the user and retry with the new credentials. WCF by itself cannot handle prompting the user.
Here is an article on various means of passing credentials:
http://blogs.msdn.com/b/sonuarora/archive/2007/04/21/setting-client-credentials.aspx