即使未提升权限,如何确定用户是不是为管理员
Posted
技术标签:
【中文标题】即使未提升权限,如何确定用户是不是为管理员【英文标题】:How to determine if user is an Administrator, even if non-elevated即使未提升权限,如何确定用户是否为管理员 【发布时间】:2012-04-20 04:07:57 【问题描述】:在我的 C# 应用程序中,我需要检查当前用户是否是管理员组的成员。它需要与 Windows XP 和 Windows 7 兼容。
目前,我正在使用以下代码:
bool IsAdministrator
get
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
问题在于,如果应用程序在 Windows 7 上以非提升管理员身份打开 UAC 运行,则此方法返回 false。即使应用程序以非提升的管理员身份运行,我如何确定用户是否是管理员?
【问题讨论】:
你为什么想知道? 嗯,首先,知道您是否是管理员可以让您知道您是否可以被提升。 @svick:如果用户是管理员组的成员,我需要显示某些 UI 元素。 看看http://www.davidmoore.info/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/ 我同意@svick - 你不应该这样做。你想要权限?尝试提升。不要假设用户将始终以未提升的管理员身份运行。作为标准用户运行并使用不同的管理员帐户进行升级是可接受的用法。顺其自然,无论用户如何工作,都让 UAC 机制完成其工作。 【参考方案1】:有一个 Win32 API GetTokenInformation
可用于检查当前令牌。如果返回的令牌是拆分令牌,则可能是在非提升模式下运行的管理员用户。
GetTokenInformation
有一个输出参数tokenInformation
,它采用以下三个值之一:
TokenElevantionTypeLimited 值表示用户正在使用具有有限权限的拆分令牌运行。当提升 TokenElevationTypeFull 值时返回。非管理员用户的值为 TokenElevationTypeDefault。
在http://www.davidmoore.info/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/有一个完整的C#代码示例
【讨论】:
谢谢,这正是我要找的。span> 链接已失效。最好将样本放在答案中吗?不确定这里的约定是什么,猜猜如果链接第 3 方,这与许可有关? @TheXenocide 样本应该在答案中(如果版权允许)。自从我写了这篇文章后,我就知道死链接是个问题。 @AndersAbel 感谢您的跟进;我只是在这里和那里参与了社区的回答方面的工作,所以很高兴知道“最佳实践”是什么。【参考方案2】:如果您是管理员,您可以暂时从代码中禁用 UAC,然后重新启用它。注册表项是
密钥:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 值:启用LUA 设置为:0 禁用,1 启用
所以你可以做类似的事情
RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\Policies\\System", true);
myKey.SetValue("EnableLUA", "1", RegistryValueKind.String);
然后检查你的校长。这有点像黑客,但值得一试。
【讨论】:
你的意思是尝试禁用,如果失败了你不是吗? 禁用系统范围的安全设置只是为了进行检查不仅仅是“一种黑客行为”。太可怕了。不要这样做。 我知道这是旧的,但这是一个可怕的想法。更不用说您必须重新启动才能再次读取此设置,因此无论如何它都不起作用。 无论如何,您都需要在您的应用中拥有管理员权限...【参考方案3】:我知道这很旧,但我发现以下方法可以在所有系统中正常工作。我需要它在 .net 2 上工作,而其他解决方案(如 WinAPI 和管理对象)在某些版本的 Windows 上失败:
启动一个运行命令net localgroup administrators
的新进程并适当地解析输出。这适用于启用和禁用 UAC 并且不需要提升的进程。
【讨论】:
【参考方案4】:对于任何 VB.NET 的人(我知道你在那里......),这是我从各种来源炮制出来的一个版本,我认为它已经过优化以确定当前用户(包括提升的用户)是否在定义的管理员组、机器或域,启用或不启用 UAC。 (很多感谢这里和其他地方的其他帖子!)
首先,它使用静态可空布尔值来保持管理员状态,因为虽然基本检查很快,但完整测试可能需要数十秒,所以你只想做一次 - 如果你愿意的话可以帮上忙。
其次,它在基本测试不正确/错误方面出错,如果用户是 AD 管理的或本地计算机启用了 UAC,通常会出现这种情况。因此,如果它可以确定用户是管理员,它会。
第三,您可以在 AuthorizationGroups 中添加或删除您认为合适的条件,但包含的条件涵盖了大多数情况。
最后,如果出现任何问题,你会得到False;如果你想要一个错误,你可以有一个,但我个人不明白这一点。
Function IsAdministrator() As Boolean
Static bResult As Boolean? = Nothing
Try
If bResult Is Nothing Then
bResult = New WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)
If Not bResult Then
Dim oContext As PrincipalContext = Nothing
Try 'to get a domain context first ...
Domain.GetComputerDomain()
oContext = New PrincipalContext(ContextType.Domain)
Catch
'... if it fails, fall through to a machine context
End Try
If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name)
If oPrincipal IsNot Nothing Then
bResult = oPrincipal.GetAuthorizationGroups().Any(Function(p) _
p.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) OrElse
p.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) OrElse
p.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) OrElse
p.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid))
End If
End If
End If
Catch
bResult = False
End Try
Return bResult.GetValueOrDefault(False)
End Function
【讨论】:
以上是关于即使未提升权限,如何确定用户是不是为管理员的主要内容,如果未能解决你的问题,请参考以下文章