จำกัด การอัปเดตในบางคอลัมน์ อนุญาตให้เฉพาะกระบวนงานที่เก็บไว้เพื่ออัปเดตคอลัมน์เหล่านั้น


17

ฉันมีคอลัมน์ราคาที่ละเอียดอ่อนซึ่งฉันต้องการอัปเดตผ่านขั้นตอนการจัดเก็บเท่านั้น ฉันต้องการรหัสทั้งหมดหรือความพยายามด้วยตนเองในการเปลี่ยนค่าในคอลัมน์ราคาเหล่านี้ให้ล้มเหลวหากไม่ได้ใช้ขั้นตอนการจัดเก็บที่ออกแบบมาเพื่ออัปเดต

ฉันกำลังพิจารณาที่จะใช้สิ่งนี้โดยใช้ทริกเกอร์และตารางโทเค็น ความคิดที่ฉันกำลังพิจารณาคือการมีตารางโทเค็น ขั้นตอนการจัดเก็บจะต้องแทรกค่าลงในตารางโทเค็นก่อน จากนั้นอัปเดตคอลัมน์ราคา ทริกเกอร์การอัพเดทจะตรวจสอบว่ามีโทเค็นอยู่ในตารางโทเค็นสำหรับแถวที่อัพเดตหรือไม่ หากพบว่ามันจะดำเนินการต่อ หากไม่พบโทเค็นจะมีข้อผิดพลาดและทำให้ธุรกรรมการอัพเดทล้มเหลว

มีวิธีที่ดี / ดีกว่าในการใช้ข้อ จำกัด นี้หรือไม่?


1
คุณสามารถใช้มุมมองสำหรับการรักษาความปลอดภัยตามคอลัมน์ นั่นจะยิ่งสวยงามกว่าทริกเกอร์ ให้สิทธิ์แก่ผู้ใช้ในมุมมอง แต่ไม่ใช่ข้อมูลพื้นฐาน
Thomas Stringer

นั่นเป็นจุดที่ดี แต่ปัญหายังคงไม่ได้รับการแก้ไขโดยไม่ทำลายแอปพลิเคชันจำนวนมากที่ใช้การรวมการเชื่อมต่อ
อีเลียส

คุณช่วยอธิบายได้ไหมว่านี่จะเป็น "การแบ่งแอพพลิเคชันจำนวนมากที่ใช้การรวมการเชื่อมต่อ" หรือไม่?
Aaron Bertrand

คำตอบ:


21

SQL Server อนุญาตการอนุญาตระดับคอลัมน์ ตัวอย่างเช่น:

GRANT UPDATE ON dbo.Person (FirstName, LastName) TO SampleRole;
DENY UPDATE ON dbo.Person (Age, Salary) TO SampleRole;

ขอบคุณ Michal แต่โซลูชันนี้ใช้งานไม่ได้เพราะแอปพลิเคชันของฉันเป็นแอปพลิเคชันเว็บที่ใช้การรวมการเชื่อมต่อ ผู้ใช้ทั้งหมดเชื่อมต่อโดยใช้สตริงการเชื่อมต่อเซิร์ฟเวอร์ SQL เดียวกัน
อีเลียส

1
@Elias ฉันไม่เข้าใจ สตริงการเชื่อมต่อเชื่อมต่อในฐานะผู้ใช้เฉพาะใช่มั้ย ดังนั้นแทนที่SampleRoleกับผู้ใช้ว่า ...
แอรอนเบอร์ทรานด์

สิทธิ์ระดับคอลัมน์เป็นวิธีไปที่นี่ สิ่งนั้นและสร้างความมั่นใจว่าผู้พัฒนารู้ว่าการเปลี่ยนแปลงค่าผ่านทาง t-sql โดยตรงจะทำลายระบบ
mrdenny

6
-- prevent your web app user from updating that column directly:

DENY UPDATE ON dbo.YourTable(Price) TO WebApplicationUserName;
GO

-- create a stored procedure while logged in as sysadmin:

CREATE PROCEDURE dbo.UpdateYourTable
  @ProductID INT,
  @Price DECIMAL(10,2)
WITH EXECUTE AS OWNER
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE dbo.YourTable 
    SET Price = @Price
    WHERE ProductID = @ProductID;
END
GO

-- grant explicit access only to that stored procedure to the web app user:

GRANT EXEC ON dbo.UpdateYourTable TO WebApplicationUserName;

2

หากผู้ใช้ทั้งหมดของคุณมีการเข้าสู่ระบบเดียวกัน (ouch, BTW) นี่คือตัวเลือกอื่น

  • เพิกถอนสิทธิ์การอัปเดตจากผู้ใช้นั้น (หรือบทบาทหากคุณทำเช่นนั้น)
  • แก้ไข proc ที่จัดเก็บไว้โดยมีคำสั่ง "execute as owner"
  • จากนั้น proc ที่จัดเก็บไว้จะทำงานโดยมีสิทธิ์ของผู้ใช้ที่เป็นเจ้าของสคีมาที่อยู่ (หากมีอยู่dboคุณจะได้รับความคุ้มครองอยู่แล้ว)

ผู้ใช้แอปพลิเคชันทั่วไปจะไม่มีสิทธิ์อัปเดตในตารางนั้นดังนั้นพวกเขาจะไม่สามารถอัปเดตด้วยวิธีอื่น


คุณไม่จำเป็นต้องสร้างผู้ใช้ใหม่เพื่อทำสิ่งนี้ ...
Aaron Bertrand

@aaronbertrand คุณพูดถูก - อีเหตุผลที่คุณคิดว่า "ทำหน้าที่เป็นผู้สร้าง" แต่นั่นไม่ใช่สิ่ง - คุณสามารถทำได้ "ดำเนินการในฐานะเจ้าของ" ตราบใดที่ผู้ใช้ที่เป็นเจ้าของสคีมามีสิทธิ์ อัปเดตตารางนั้น หาก proc ที่จัดเก็บอยู่ใน dbo คุณก็จะได้รับความคุ้มครอง ฉันจะอัปเดตคำตอบของฉัน
SqlRyan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.