我创建了两个对应于两个 Windows 组的 SQL Server 登录名:
MachineName\MyAppAmdin
MachineName\MyAppUser
然后在数据库中,我创建了两个具有相同名称的用户并将它们映射到登录名。
在 windows 服务器中,我将我的域帐户添加MyDomain\MyAccount
到MachineName\MyAppAmdin
组中。
现在我可以通过MyDomain\MyAccount
.
问题是,我想确切地知道我正在使用哪个 Windows 组登录,但我不知道如何。
我试过了:
ORIGINAL_LOGIN()
SYSTEM_USER
SUSER_SNAME
SELECT * FROM dm_exec_sessions
以上所有返回MyDomain\MyAccount
,但我需要知道的是我是否通过组成员身份登录MachineName\MyAppAmdin
。
总结一下,我的问题是:
有没有办法准确判断当前连接正在使用哪个 Windows 组登录(或用户)?
或者有什么方法可以检查是否MyDomain\MyAccount
与特定用户或登录相关联?
我知道如果域帐户属于特定的 Windows 组,我可以使用 C# 或命令来解析,但是我们有一些新的 IT 策略,所以我正在考虑使用 TSQL 实现类似结果的方法。
SQL Server 中的 Windows 身份验证并非完全如此。当您以具有关联登录名的域用户身份登录,但也可以通过具有关联登录名的域组访问时,访问权限由组合的 DENY/GRANT 权限和分配给这两个用户的 SQL\DB 角色成员身份确定登录和组登录。
没有作为组“登录”的概念,组只是一个容器,用于根据 Active Directory 中该组的成员身份提供对域用户集合的访问。
您可以通过运行以下命令检查特定用户的各种访问路径:
这将列出用户的各种访问路径,即此 Windows 帐户链接到的所有组登录和用户登录。
Windows Authentication
是token-based
身份验证,您可以在tokens
此处阅读访问令牌和此处基于令牌的身份验证因此,当您用于
Windows Authentication
登录时,您将向服务器展示您的Windows token
.login token
您可以使用以下代码查看属于您的所有服务器主体:如果你想探索
login token
另一个登录,你应该首先模拟它:当然,您应该获得
IMPERSONATE
许可some_login
才能使用impersonate
它。因此,您对服务器的权限是根据构成您的令牌的所有主体的权限的“总和”定义的。
DENY
一如既往地具有优先权,GRANT
因此,如果您是某个对象上的两个Win groups
wichgrant
和另一个的成员deny
,您将被拒绝访问它。虽然HandyD 的答案和sepupic 的答案都有很好的信息,但仍然需要一些澄清。
当您使用 Windows 身份验证登录时,您的安全上下文包括映射到与当前 Windows 安全上下文匹配的所有登录。
sys.server_principals
这可以是 Windows 登录和/或一个或多个 Windows 组。如果您的 Windows 帐户位于 5 个组中,其中 3 个组在 SQL Server 中注册为登录名,但没有专门为您提供登录名,则您的安全上下文将只是这 3 个组。如果您随后专门为您的 Windows 帐户添加了登录,那么登录将为您提供 Windows 登录以及所有 3 个映射组的安全上下文。xp_logininfo很有帮助,因为它可以显示匹配的映射组和/或帐户登录,而无需以帐户身份登录或模拟帐户。它可以让您查看 Windows 组的成员(如果 Windows 组在 SQL Server 中注册为登录名)。
这个系统存储过程不能显示的是:
xp_logininfo
不会显示包含数据库的任何内容,因为它仅在实例级排序规则是Latin1_General_100_CI_AS_KS_WS_SC
由于我在测试时发现的错误引起的情况下才在其中工作:xp_logininfo 获取“消息 468,级别 16,状态 9:无法解决排序规则冲突...”当数据库排序规则与实例排序规则不匹配时)sys.login_token有助于查看完整的安全上下文,包括 Windows 登录(如果有一个映射)和/或任何 Windows 组(如果有映射),以及登录和/或组的服务器级角色是的成员。“有效”权限基于所有安全令牌的所有权限,并且 a
DENY
覆盖任何GRANT
s。因此,您可以通过组 1 的成员资格授予您对某事的权限,但组 2 是已被拒绝该权限(或父权限)的服务器级角色的成员,因此您实际上被拒绝了该权限。这个 DMV 不能显示的是:
sys.user_token有助于在数据库级别查看完整的安全上下文。每个数据库的安全令牌可能不同,因此在检查此 DMV 时,有效权限始终基于当前数据库。当直接登录到包含的数据库时,此 DMV 是更相关的信息。
这是我通常用来找出正在使用的用户的方法:
但是,它不会返回当前 Windows 组,通过该组授予用户访问数据库的权限。
为了测试上述内容,或者有时为了测试一些权限或程序,我做了类似于以下示例的操作:
以下脚本没有告诉您当前登录使用哪个组,但在很多情况下它对我非常有用
我发现
IS_MEMBER()
可以验证当前用户是否是我创建的 windows 组的成员。