I am trying to use WCF to do some remote user management things. I and reusing some code I had on a server 2003 box and worked fine, but on my windows 7 test box when I check to see if the user who called the function is administrator it says it is not.
[OperationBehavior(Impersonation=ImpersonationOption.Required)]
public string SetPassword(string username)
{
WindowsPrincipal principal = new WindowsPrincipa开发者_运维问答l(OperationContext.Current.ServiceSecurityContext.WindowsIdentity);
System.Diagnostics.Debug.Print(WindowsIdentity.GetCurrent().Name);
System.Diagnostics.Debug.Print(principal.Identity.Name);
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
//try
{
lock (Watchdog.m_principalContext)
{
using (UserPrincipal up = UserPrincipal.FindByIdentity(Watchdog.m_principalContext, username))
{
string newpassword = CreateRandomPassword();
up.SetPassword(newpassword);
up.Save();
return newpassword;
}
}
}
//catch
{
return null;
}
}
else
throw new System.Security.SecurityException("User not administrator");
}
principal.IsInRole(WindowsBuiltInRole.Administrator)
is returning false every time. Both my current identity and principal.idenity are the correct user to be impersonated. and that user is a member of the administrators user group.
I think it has to do with UAC that was implemented in windows vista and up. this will be a issue because the production machine this will be going on to is a win2k8-r2 box.
Any suggestions on what to do?
Take a look at this article, under the section, "Coping with Windows Vista" , a very well written article with about UAC and checking Admin privs programatically.
As I did not want to do all that work (from RandomNoob's post) for check if the user is an administrator and the service is already running in a administrative context, I decided to just drop impersonation. I created a new user group called WCFUsers and anyone who will be using the service was added to that group. It now does the System.DirectoryServices.AccountManagement
operations in its own context.
[OperationBehavior(Impersonation=ImpersonationOption.NotAllowed)]
public string SetPassword(string username)
{
WindowsPrincipal principal = new WindowsPrincipal(OperationContext.Current.ServiceSecurityContext.WindowsIdentity);
if (principal.IsInRole("WCFUsers"))
{
try
{
lock (Watchdog.m_principalContext)
{
using (UserPrincipal up = UserPrincipal.FindByIdentity(Watchdog.m_principalContext, username))
{
string newpassword = CreateRandomPassword();
up.SetPassword(newpassword);
up.Save();
return newpassword;
}
}
}
catch
{
return null;
}
}
else
return null;
}
精彩评论