it-swarm.asia

تلقي "تم رفض إذن SELECT على الكائن" على الرغم من أنه تم منحه

أنا مبرمج ، ولست dba ... أعرف ما يكفي لتكون خطيرة.

لقد ورثت قاعدة بيانات مع مستخدم قديم يمثل db_owner لقاعدة البيانات. لا يمكننا تعديل إذن هذا المستخدم للجداول والمخططات الحالية وما إلى ذلك ، لأسباب تجارية ، ولكن يتم إنشاء بعض الجداول الجديدة ، وأريد فقط أن يحصل هذا المستخدم على SELECT للوصول إليها.

تم تعيين الأذونات لهذا المستخدم لهذه الجداول بحيث يتم رفض كل شيء ، باستثناء SELECT ، التي تم تعيينها على GRANT.

ومع ذلك ، عندما يحاول هذا المستخدم (dbadmin) إجراء SELECT على أحد هذه الجداول (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 * FROM AccountingAudit الأساسية للغاية ، من داخل SSMS. أنا لا أقوم بأي sp_executesql خاص أو أي شيء من هذا القبيل.

لقد حاولت منح الإذن صراحة:

GRANT SELECT ON [dbo].AccountingAudit TO dbadmin

هذا ليس له تأثير (لماذا ، يظهر الاستعلام أعلاه بالفعل أنه تم منحه! ؛-)

لقد بحثت عبر موقع stackoverflow.com وأماكن أخرى ، ولم أجد أي شيء لم أجربه بعد. أتساءل عما إذا كان لها علاقة بكيفية إعداد المخططات. (في هذه المرحلة ، أعرف القليل جدًا عن المخططات.)

أيه أفكار؟ شكر!

11
Mason G. Zhwiti

لست متأكدًا هنا ، لكنني سأخرج على أحد الأطراف. أعتقد أن مشكلتك قد تكون مع DENY CONTROL سجل. انظر هنا حوالي منتصف الطريق أسفل الصفحة:

رفض إذن التحكم في قاعدة بيانات يرفض ضمنيًا إذن CONNECT في قاعدة البيانات. لن يتمكن الموصل الذي تم رفض إذن التحكم في قاعدة بيانات من الاتصال بقاعدة البيانات هذه.

أدرك أن هذا المثال مخصص لقاعدة بيانات ، ولكن خذها بمستوى واحد إضافي. أ DENY CONTROL على الطاولة سوف يرفض all امتيازات عليه ، على ما أعتقد. هل REVOKE CONTROL للتخلص من ذلك ومعرفة ما إذا كان ذلك سيصلح مشكلتك.

إذا كان الأمر كذلك ، فسيتعين عليك وضع المستخدم في دور قاعدة بيانات أو حرمانه من الامتيازات الصريحة مقابل الجدول.

10
Thomas Stringer
  1. استخدم الإجراء المخزن لـ Ken Fisher sp_DBPermissions للنظر في الأذونات.

    1. تأكد من عدم تطبيق DENY CONTROL على الجدول ، بالإضافة إلى DENY SELECT و DENY INSERT و DENY UPDATE و DENY DELETE و DENY REFERENCES.
    2. إذا كانت العبارة SELECT تحتوي على دالات بقيمة الجدول ، فتأكد من وجود EXECUTE AS OWNER في دالة قيم الجدول أو GRANT EXECUTE عليها (ولا يوجد DENY EXECUTE! ). إذا كان هذا هو الحال ، فقم بقراءة رسالة الخطأ بعناية أكبر حيث من المحتمل ألا تقول أن إذن SELECT تم رفضه على الطاولة ، ولكن بدلاً من ذلك تم رفض شيء ما بشأن EXECUTE.
  2. إذا كان المستخدم مستخدمًا أو مجموعة إعلانية ، فاستخدم النص البرمجي التالي لتحديد login_token (s) للمستخدم:

EXECUTE AS LOGIN = 'EXAMPLEDOMAIN\JOHN.DOE';
SELECT * FROM sys.login_token;
REVERT;
  1. انظر إلى خطة التنفيذ الفعلية. إذا كان الخطأ داخل إجراء مخزّن يحتوي على SET NOCOUNT ON; ، فستمنحك خطة التنفيذ الفعلية نظرة ثاقبة قد لا تنتبه إليها بمجرد النظر إلى علامة التبويب "الرسائل" في SSMS ، نظرًا لأن "الصفوف المتأثرة" قد تكون خارج نطاق سيطرتك .

    1. ابحث عن المشغلات أو الجداول الزمنية.
  2. يمكنك ترجمة البيان كإجراء مخزّن و "عرض تبعيات الكائن" لـ SSMS ، بالإضافة إلى الحيل التي حددها Svetlana Golovko في طرق مختلفة للعثور على تبعيات كائن SQL Server

  3. استخدم حدث SQL Server Profiler Security "حدث الوصول إلى كائن مخطط التدقيق" والأعمدة "TextData" و "Success" لتتبع الكائنات التي يقوم 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. إذا كان المستخدم مرتبطًا بمستخدم أو مجموعة م ، ففكر في تشغيل repadmin /syncall لفرض أي تغييرات تم إجراؤها في Active Directory للمزامنة عبر وحدات تحكم المجال. - إذا كان هناك شخص يعرف طريقة جيدة لمقارنة القيم الحالية لوحدتي تحكم المجال ، فيرجى إبلاغي بذلك.

  2. قبل التفكير في إعادة تشغيل النظام بالكامل ، حاول قتل جميع الاتصالات النشطة لهذا المستخدم. السبب هو حصول المستخدم على رمز windows الخاص به من DC الذي يتضمن مجموعاته. لن يتم تحديث الرمز المميز حتى يحصل المستخدم على رمز مميز جديد - عادةً عن طريق تسجيل الخروج ثم تسجيل الدخول مرة أخرى .

  3. إعادة تشغيل النظام بجد. نفعني. لا يزال غير متأكد بنسبة 100 ٪ لماذا حتى الآن. افعل هذا فقط إذا كان بإمكانك البقاء على قيد الحياة مرة أخرى! كن حذرا بشأن القيام بذلك بينما لديك معاملات كبيرة معلقة!

0
John Zabroski