การรับ“ สิทธิ์ SELECT ถูกปฏิเสธบนวัตถุ” แม้ว่าจะได้รับอนุญาตแล้วก็ตาม


11

ฉันเป็นโปรแกรมเมอร์ไม่ใช่ dba ... ฉันรู้ว่าเพียงพอที่จะเป็นอันตราย

ฉันได้รับมรดกฐานข้อมูลด้วยผู้ใช้ดั้งเดิมที่เป็น db_owner สำหรับฐานข้อมูล เราไม่สามารถปรับการอนุญาตของผู้ใช้นี้สำหรับตาราง schema ที่มีอยู่ ฯลฯ ด้วยเหตุผลทางธุรกิจ แต่มีการสร้างตารางใหม่บางตารางขึ้นและฉันต้องการให้ผู้ใช้นี้มีสิทธิ์เข้าถึง SELECT เหล่านั้นเท่านั้น

มีการตั้งค่าการอนุญาตสำหรับผู้ใช้นี้สำหรับตารางเหล่านี้เพื่อให้ทุกอย่างถูกปฏิเสธยกเว้น SELECT ซึ่งตั้งค่าเป็น GRANT

แต่เมื่อผู้ใช้นี้ (dbadmin) พยายามทำการเลือกบนหนึ่งในตารางเหล่านี้ (AccountingAudit) ข้อผิดพลาดนี้เกิดขึ้น:

The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.

ฉันใช้ SQL นี้เพื่อลองดูว่ามีการตั้งค่าการอนุญาตสำหรับตาราง / ผู้ใช้นี้:

select object_name(major_id) as object,
 user_name(grantee_principal_id) as grantee,
 user_name(grantor_principal_id) as grantor,
 permission_name,
 state_desc
from sys.database_permissions

และนี่คือสิ่งที่ฉันได้รับ:

AccountingAudit dbadmin dbo ALTER   DENY
AccountingAudit dbadmin dbo CONTROL DENY
AccountingAudit dbadmin dbo DELETE  DENY
AccountingAudit dbadmin dbo INSERT  DENY
AccountingAudit dbadmin dbo REFERENCES  DENY
AccountingAudit dbadmin dbo SELECT  GRANT
AccountingAudit dbadmin dbo TAKE OWNERSHIP  DENY
AccountingAudit dbadmin dbo UPDATE  DENY
AccountingAudit dbadmin dbo VIEW DEFINITION DENY
AccountingAudit dbadmin dbo VIEW CHANGE TRACKING    DENY

ดูเหมือนว่ามันควรจะทำงานใช่มั้ย

การเรียก SELECT ที่ฉันกำลังทำนั้นเป็น SELECT ขั้นพื้นฐานอย่างยิ่งจาก AccountingAudit จากภายใน SSMS ฉันไม่ได้ทำอะไรเป็นพิเศษ sp_executesql หรืออะไรทำนองนั้น

ฉันพยายามให้สิทธิ์อย่างชัดเจน:

GRANT SELECT ON [dbo].AccountingAudit TO dbadmin

สิ่งนี้ไม่มีผลกระทบ (เพราะเหตุใดแบบสอบถามด้านบนจึงแสดงว่าได้รับแล้ว! ;-)

ฉันค้นหาผ่าน stackoverflow.com และที่อื่น ๆ แล้วและไม่พบสิ่งที่ฉันยังไม่ได้ลอง ฉันสงสัยว่ามันมีบางอย่างเกี่ยวกับวิธีการตั้งค่า schema (ณ จุดนี้ฉันรู้เรื่องสคีมาน้อยมาก)

ความคิดใด ๆ ขอบคุณ!

คำตอบ:


10

ฉันไม่แน่ใจที่นี่ แต่ฉันจะออกไปที่กิ่ง ฉันคิดว่าปัญหาของคุณอาจมีDENY CONTROLบันทึกของคุณ ดูที่นี่ประมาณครึ่งหน้า

การปฏิเสธการควบคุมสิทธิ์บนฐานข้อมูลโดยนัยปฏิเสธการอนุญาต CONNECT ในฐานข้อมูล ตัวการที่ถูกปฏิเสธสิทธิ์การควบคุมบนฐานข้อมูลจะไม่สามารถเชื่อมต่อกับฐานข้อมูลนั้นได้

ฉันรู้ว่าตัวอย่างนั้นใช้สำหรับฐานข้อมูล แต่ลองใช้อีกระดับหนึ่งที่ละเอียดยิ่งขึ้น A DENY CONTROLบนโต๊ะจะปฏิเสธสิทธิพิเศษทั้งหมดบนโต๊ะฉันคาดเดา ทำREVOKE CONTROLเพื่อกำจัดสิ่งนั้นและดูว่าสิ่งนั้นสามารถแก้ไขปัญหาของคุณได้หรือไม่

ถ้าเป็นเช่นนั้นคุณจะต้องวางผู้ใช้ในบทบาทฐานข้อมูลหรือปฏิเสธสิทธิ์ที่ชัดเจนต่อตาราง


1
ขอบคุณ! ตอนแรกในการทดลองของฉันฉันค้นพบว่าถ้าควบคุมไม่ได้ถูกปฏิเสธพวกเขาก็สามารถเลือกได้ แต่ในการอ่าน BOL ฉันตีความผิดพลาดนี้เพื่อให้ผู้ใช้สามารถควบคุมตารางได้อย่างเต็มที่ ฉันเห็นแล้วว่าตราบใดที่ฉันไม่ปฏิเสธพวกเขาควบคุมฉันยังสามารถเก็บสิทธิ์อื่น ๆ (INSERT, DELETE, ฯลฯ ) ในระดับ DENY และบรรลุระดับสิทธิ์ที่ฉันต้องการ ขอบคุณ!
Mason G. Zhwiti

นี่เป็นความละเอียดอ่อนที่ฉัน upvoted แม้ว่าจะไม่ได้แก้ปัญหาของฉันที่ฉันรู้สึกว่าส่วนใหญ่จะมองข้าม แยกกันฉันพบว่าใช้กลุ่ม Active Directory หากคุณเปลี่ยนการเป็นสมาชิกกลุ่ม repadmin / syncall ไม่จำเป็นต้องแก้ไขปัญหาและฉันพบว่าการรีบูตเซิร์ฟเวอร์แก้ไขปัญหา ยังคงมองหาวิธีการค้อนขนาดเล็กน้อยกว่า
John Zabroski

0
  1. ใช้sp_DBPermissionsขั้นตอนการจัดเก็บของ Ken Fisher เพื่อดูการอนุญาต

    1. ให้แน่ใจว่าDENY CONTROLจะไม่นำไปใช้กับตารางที่นอกเหนือไปจากที่พบบ่อยDENY SELECT, DENY INSERT, DENY UPDATE, และDENY DELETEDENY REFERENCES
    2. หากSELECTคำสั่งมีฟังก์ชั่นที่ให้คุณค่ากับตารางตรวจสอบให้แน่ใจว่ามีEXECUTE AS OWNERฟังก์ชั่นที่ให้คุณค่ากับตารางหรือฟังก์ชั่นGRANT EXECUTEนั้น (และไม่ใช่DENY EXECUTE!) หากเป็นกรณีนี้ให้อ่านข้อความแสดงข้อผิดพลาดอย่างระมัดระวังมากขึ้นเนื่องจากไม่น่าจะบอกได้ว่า SELECT ได้รับการปฏิเสธบนโต๊ะ แต่มีบางอย่างเกี่ยวกับ EXECUTE ที่ถูกปฏิเสธ
  2. หากผู้ใช้เป็นผู้ใช้ AD หรือกลุ่มใช้สคริปต์ต่อไปนี้เพื่อตรวจสอบผู้ใช้login_token:

EXECUTE AS LOGIN = 'EXAMPLEDOMAIN\JOHN.DOE';
SELECT * FROM sys.login_token;
REVERT;
  1. ดูแผนการดำเนินการจริง หากข้อผิดพลาดอยู่ในขั้นตอนการจัดเก็บด้วยSET NOCOUNT ON;แผนปฏิบัติการจริงจะให้ข้อมูลเชิงลึกที่คุณอาจไม่ได้สนใจเพียงดูที่แท็บข้อความใน SSMS เนื่องจาก "แถวที่ได้รับผลกระทบ" อาจอยู่นอกการควบคุมของคุณ

    1. มองหาทริกเกอร์หรือตารางชั่วคราว
  2. คุณสามารถรวบรวมคำสั่งเป็นกระบวนงานที่เก็บไว้และ SSMS "ดูการอ้างอิงวัตถุ" เช่นเดียวกับเทคนิคที่อธิบายไว้โดย Svetlana Golovko ด้วยวิธีต่างๆในการค้นหาการพึ่งพาวัตถุเซิร์ฟเวอร์ SQL

  3. ใช้เหตุการณ์การรักษาความปลอดภัยของผู้สร้างโปรไฟล์เซิร์ฟเวอร์ SQL "ตรวจสอบเหตุการณ์การเข้าถึงวัตถุ Schema" และคอลัมน์ "TextData" และ "ความสำเร็จ" เพื่อติดตามวัตถุที่ SQL Server กำลังประเมินสิทธิ์ - ฉันได้เห็นสถานการณ์ที่มีการปล่อยสองแถวสำหรับเหตุการณ์นี้และค่าหนึ่งบอกว่าสำเร็จ = 1 และอีกหนึ่งบอกว่าสำเร็จ = 0 ในสถานการณ์นี้โซลูชันเดียวที่ฉันพบว่าทำงานคือรีบู๊ตเซิร์ฟเวอร์ แม้การทำงานrepadmin /syncallไม่ได้ช่วยแก้ปัญหา แต่ก็ไม่ได้เริ่มต้นและหยุดแอปพลิเคชัน (และรวมถึงการเชื่อมต่อ)

  4. กำหนดสิทธิ์ที่มีประสิทธิภาพสำหรับการเข้าสู่ระบบ:

-- '<domain>\<username>' is a domain user in the group you wish to test
EXECUTE AS LOGIN = '<domain>\<username>';
SELECT * FROM fn_my_permissions('Database.Schema.Table', 'OBJECT');
REVERT;
  1. หากผู้ใช้เชื่อมโยงกับผู้ใช้ AD หรือกลุ่มให้พิจารณาการเรียกใช้repadmin /syncallเพื่อบังคับให้การเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นในไดเรกทอรีที่ใช้งานเพื่อซิงค์ทั่วทั้งตัวควบคุมโดเมนของคุณ - หากมีคนรู้วิธีที่ดีในการเปรียบเทียบค่าปัจจุบันของตัวควบคุมโดเมนทั้งสองโปรดแจ้งให้เราทราบ

  2. ก่อนที่จะพิจารณาการรีบูตระบบทั้งหมดให้ลองฆ่าการเชื่อมต่อที่ใช้งานอยู่ทั้งหมดของผู้ใช้รายนั้น เหตุผลก็คือผู้ใช้จะได้รับโทเค็นหน้าต่างจาก DC ซึ่งรวมถึงกลุ่มของพวกเขา โทเค็นจะไม่ได้รับการอัปเดตจนกว่าผู้ใช้จะได้รับโทเค็นใหม่ - โดยการออกจากระบบจากนั้นเข้าสู่ระบบอีกครั้ง

  3. รีบูตระบบอย่างหนัก มันได้ผลสำหรับฉัน ยังไม่แน่ใจ 100% ว่าทำไม ทำเช่นนี้หากคุณสามารถอยู่รอดได้ตลอดเวลา! ระมัดระวังเกี่ยวกับการทำเช่นนี้ในขณะที่คุณมีการทำธุรกรรมขนาดใหญ่ที่โดดเด่น!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.