2014-12-03 65 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