我目前面臨的一個問題,在那裏我有服務器名稱的列表,我需要驗證Windows身份驗證的用戶有權限指定的服務器名稱,而不會嘗試與指定的服務器建立連接,然後向服務器列出服務器。因此,例如:
服務器:A,B,C,d
喬有權A和d,但不是B和C等等喬應該只看到A和d在他的服務器列表。
我該如何解決這個問題?我應該從Active Directory中拉出嗎?我知道如何拉取我的用戶身份,但是在哪裏拉取服務器信息並查明用戶是否擁有權限是一個完全不同的故事。任何文檔,代碼示例,文章等都很有幫助。
事項有關的工作環境
- 在列表中的服務器的所有正在運行的SQL Server 2008 R2和更高的數據庫服務器。
- 這是一個嚴格限制的政府環境。
- 我無法以任何方式修改Active Directory。
- 如果用戶有權限,我可以整天查詢Active Directory和SQL Server。
- 使用第三方庫和工具未經授權。
旁註關於服務器列表
該列表存儲在數據庫中,但我不認爲與權限方面這確實有幫助。我已經通過以下SQL查詢解決了針對單個數據庫檢查權限的問題:
SELECT name
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
ORDER BY name
感謝您的幫助!
-Jamie
結論
從本質上講,我已經發現沒有可能的方式來查詢遠程服務器上的AD組而不嘗試建立連接,從而所有樣品的執行發現將用IA標記用戶帳戶。對於其他類似問題的用戶不必擔心IA對用戶的影響,我在下面列出了幾個解決方案,您可以嘗試滿足您的需求(以下所有內容在正確實施時均可用)。
解決方案
- 查詢在Active Directory服務器和從服務器中檢索組,如果失敗9十次中有異常信息將是「訪問被拒絕。」。如果成功,請繼續提取當前用戶的組並與從服務器拉出的組進行比較。選定的答覆這個職位結合this post和/或this post會讓你需要這個解決方案。
如果您已經通過impersonation或其他手段(SQL Server Auth),訪問服務器,那麼你可以使用下面來看看成員具有分配任何服務器角色:
SELECT IS_SRVROLEMEMBER('public')
你也可以使用Microsoft.SqlServer.Management.Smo命名空間使用Microsoft.SqlServer.Smo程序集中的可用Login class。但是,將Microsoft.SqlServer.SqlClrProvider命名空間從GAC移動到BIN可能會也可能沒有問題。關於這方面更多的信息可以在this StackOverflow post發現,在this微軟連接螺紋,其規定如下:
客戶端應用程序不應該使用的組件從Program Files文件夾,除非他們是從特定的SDK文件夾(如 「C:\ Program Files文件(x86)的\ Microsoft SQL Server的\ 130 \ SDK」)
你甚至可以做一個基本的連接測試裹着嘗試捕捉以查看連接是否可用。
using (SqlConnection conn = new SqlConnection(connString)) { try { conn.Open(); conn.Close(); } catch (Exception e) { Console.Write($"Connection test failed: {e.Message}"); } }
有少量多樣的方式來實現的總體目標,它只是取決於你的具體情況和您要如何處理它。對我而言,這些解決方案都不會起作用,因爲在每種情況下,測試都會嘗試連接到正在討論的服務器,這會由於缺少權限而標記用戶。
你的意思是你想檢查單個服務器的syslogins嗎? – SchmitzIT
我需要驗證用戶有權訪問數據庫服務器。我會假設沒有涉及SQL查詢,但如果有的話會很好。我假設這很可能是一個Active Directory查詢。 – lxxtacoxxl
那麼,sys.server_principals將包含有關在服務器上創建了哪些用戶的信息。只要用戶登錄,您就可以隨時輪詢您的SQL Server,並只顯示他們已添加爲有權訪問的用戶。不知道是否有更好的AD方式,但可能必須將兩者結合使用,因爲SQL也可以接受組的成員 – SchmitzIT