2014-12-03 63 views
5

SQL Server如何在不明确的情况下处理登录,例如,Windows用户帐户和包含此用户的AD组都存在登录名?具有为用户和包含AD组的用户创建的登录Windows用户的数据库级权限?

我们在Active Directory和来自该AD的组中有Windows用户的SQL Server 2008权限问题。我会试着用一个例子来解释。

想象一下,属于AD群组的Windows域用户DOMAIN\myUserDOMAIN\SomeGroup

在SQL Server中,我有2个数据库SomeAppDbPublicDb

目标是成为DOMAIN\SomeGroup成员的所有用户都应该能够访问PublicDb,但只有DOMAIN\myUser应该能够访问SomeAppDb

最初,在SQL Server中的Windows登录DOMAIN\SomeGroup(映射到AD组)上的实例创建,一个用户在数据库中PublicDb适当角色成员创建的,而且效果很好,从组SomeGroup用户可以访问他们需要的数据PublicDb

针对新应用程序的需求,我们希望为数据库SomeAppDb显式访问用户DOMAIN\myUser,同时仍允许访问PublicDb。因此,我们在SQL Server中创建一个Windows登录为DOMAIN\myUser,并且用户在数据库中创建SomeAppDb,与2

之间的映射从那一刻开始,预期MYUSER可以访问SomeAppDb,但不能再访问PublicDb和我们有一样的错误:

Cannot open database "PublicDb" requested by the login. The login failed. 
Login failed for user 'DOMAIN\myUser' 

我的直觉告诉我,当用户访问SQL Server实例,SQL Server将看到一个登录比赛的Windows用户,而忽略现有的一组用户的登录属于。

一种方法是在用户myUser的db PublicDb上明确添加访问权限,但我宁愿避免使用该解决方案,因为每次我们想要访问新用户时都会强制更新PublicDb,这正是我们试图避免的最初......(我们做了临时修复,希望找到更好的选择)。

有其他人遇到过这个问题吗?有更好的方法吗?

在此先感谢

+0

我的问题也许应该移到http://dba.stackexchange.com? – tsimbalar 2014-12-03 21:22:45

+0

只是好奇,如果你有机会测试任何建议的测试和验证组的成员等事情? – 2014-12-10 04:26:39

+1

本周事情变得很疯狂,但我希望在本周结束之前我会深入一点。谢谢 – tsimbalar 2014-12-10 18:34:04

回答

7

我的直觉告诉我,当用户访问SQL Server实例,SQL Server将看到一个登录比赛的Windows用户,而忽略现有的用户所属的组登录至。

这种直觉是不正确的。这是一件好事,因为您希望安全设置工作的方式就是应该正在工作;权限是附加的。我刚刚重现了您的设置,并且为Windows登录创建登录对权限没有任何不利影响(即,特定的数据库访问权限),只分配给基于Windows组的登录。我甚至可以将基于Windows登录的登录的默认数据库设置为只能通过与基于Windows组的登录相关的映射访问的数据库。是的,我的测试登录只是public服务器和数据库角色的成员,而且我确实验证了没有明确映射到基于Windows组的登录或基于Windows登录的登录的任何数据库根本无法访问。

所以,我非常肯定,有些事情已经改变了之外,或者其他一些配置正在创造这种情况。但首先,我们应该清楚确切的问题。问题的说明指出:

从那一刻起如预期,MYUSER可以访问SomeAppDb,但不能再访问PublicDb

这有意味着myUser能够登录。但是,用户无法通过USE [PublicDb]更改为PublicDb?或者我们在谈论别的什么?可能是其他内容所暗示的确切错误信息:

无法打开登录所请求的数据库“PublicDb”。登录失败。 登录失败,用户“域\ MYUSER”

如果myUser在记录和简单地改变数据库,或做跨数据库查询,那么就不会出现“登录失败”错误消息。这导致我怀疑缺省数据库(或连接字符串中指定的数据库)为SomeAppDb,并且如前所述,这里没有问题。但是,它必须是一个指定“PublicDb”的连接字符串,它有问题。如果是这样,那么同样的连接字符串,复制和粘贴(不重新输入)为别人工作?也许在指定“PublicDb”的连接字符串中有一个typeo,甚至是一个隐藏的字符?我已经能够重现错误的唯一方法是通过SQLCMD连接,同时指定一个数据库:

  • 不存在
  • 存在,该帐户已经获得,但有大约名方括号(如-d "[PublicDb]"
  • 存在,但该帐户没有访问(意思是,有更多的事情来测试,如下;-)

指出如果没有一个连接字符串的问题,这里有一些事情要检查:

  1. 虽然DOMAIN\myUser登录到SQL Server,DOMAIN\myUser应运行以下命令:

    -- http://msdn.microsoft.com/en-us/library/ms186271.aspx (IS_MEMBER) 
    SELECT IS_MEMBER(N'DOMAIN\SomeGroup'); 
    

    如果登录是真的该组中,那么它会返回一个1。如果没有,则:

    • 0意味着登录是Windows登录但不是在集团,那么它从该组中删除,或
    • NULL意味着这是不是Windows登录(似乎是不可能的,因为在SQL Server登录名称具有\这是不是一个SQL Server登录的有效字符)
  2. 虽然DOMAIN\myUser登录到SQL Server:

    1. 删除DOMAIN\myUser用户在PublicDb的临时修复。
    2. DOMAIN\myUser应运行以下命令:

      SELECT HAS_DBACCESS(sd.[name]) AS [HasAccess], * 
      FROM sys.databases sd 
      ORDER BY 1 DESC, [name] ASC; 
      

      是否PublicDb在列表中显示出来?

  3. 运行以下查询:

    SELECT * 
    FROM sys.server_principals 
    WHERE [name] IN ('DOMAIN\myUser', 'DOMAIN\SomeGroup'); 
    

    检查以下字段:sidtype_descdefault_database_name。确保“默认数据库”是一个真正的数据库。当您最初为DOMAIN\myUser添加登录时,可能是该值设置不正确。如果没有别的,也许尝试将其设置为[master]以查看是否能够避免该错误。如果可行,请将其设置回[PublicDb]

  4. 有 “MYUSER” 登录到Windows,进入命令提示符,然后运行:

    SQLCMD -E -Q"SELECT DB_NAME(), USER; USE [PublicDb]; SELECT DB_NAME(), USER;" 
    

    第一行返回的应该是SomeAppDb DOMAIN\myUser。然后是关于切换数据库上下文的消息。然后他们应该看到PublicDb DOMAIN\myUser

    • 如果是的话,那么这绝对不是“db访问”问题。
    • 如果否,那么此登录不再是该组的一部分,或者某个具体的东西阻止了它。在这种情况下,当为“DOMAIN\myUser”添加特定登录之后,“在数据库SomeAppDb中创建了用户,并在2之间进行映射”如拒绝任何服务器级别或数据库级别的权限?
  5. 有 “MYUSER” 登录到Windows,进入命令提示符,然后运行:

    SQLCMD -E -Q"SELECT DB_NAME(), USER;" -d"PublicDb" 
    

    他们应该得到一个返回行是PublicDb DOMAIN\myUser。如果是的话,那么这绝对不是一个“登录”问题。

  6. 一个简单的测试将是:
    1. 创建一个新的Active Directory帐户
    2. 这个帐户的域\ SomeGroup“
    3. 登录会员到Windows作为这个帐户
    4. 连接到SQL Server
    5. 尝试访问这两个数据库。该帐户应该能够从SQL Server
    6. 只能访问PublicDb
    7. 断开该测试Windows帐户
    8. 为登录创建SomeAppDb用户(没有额外的选项)创建SQL Server中的登录(如CREATE USER [DOMAIN\myUser] FOR LOGIN [DOMAIN\myUser]
    9. 连接到SQL Server
    10. 尝试访问这两个数据库。该帐户现在应该可以。
  7. 要测试的最后一件事是删除所有看起来是这个错误的原因。所以摆脱DOMAIN\myUser用户SomeAppDb,然后摆脱DOMAIN\myUser登录。如果其中一件事确实导致了这个错误,那么此时DOMAIN\myUser应该能够再次访问PublicDb
  8. 什么其他Windows组是Windows登录的成员(至少任何将有一个登录)?
  9. 你说的是什么“角色成员”?这些内置角色还是自定义角色?

P.S.大多数处理相同错误的相关帖子(最终都会出现这种情况)最终会创建一个SQL Server登录帐户,或者将基于Windows的登录名添加到“db_owner”角色中。我认为这两种解决方案都是阴谋诡计,并且计算机的行为并不是任意的,所以我们只需要找出原因。

+1

非常感谢,我会再检查一下实际配置是什么,并且很可能将您的答案标记为已接受,因为它非常完整! – tsimbalar 2014-12-10 18:33:18

+0

@tsimbalar谢谢,没有问题。另外,如果您在完全搞清楚之前将其标记为已接受(例如,赏金不会进入/ dev/null ;-),我将继续为您提供帮助,直至解决问题。需要至少有一个记录在案的情况下,在网络上的某个地方包含一个修复程序,所以我愿意坚持下去:) – 2014-12-10 18:36:50

+1

好吧,我会这样做的,这里是赏金! :P – tsimbalar 2014-12-11 09:19:59