راهنمای جامع توابع امنیتی SQL Server | مرجع تخصصی SQL Server

راهنمای جامع توابع امنیتی SQL Server

توسط admin | گروه SQL Server | 1405/04/29

نظرات 0

راهنمای جامع توابع امنیتی SQL Server

دسترسی سریع

این مجموعه مرجع کاربردی برای تشخیص هویت، نگاشت Principal و طراحی Audit در SQL Server است. هر پیوند به آموزش مستقل همان تابع می‌رسد.

مقدمه‌ای بر مدل امنیت SQL Server

مدل امنیتی SQL Server چندلایه است. Login در سطح Instance، User در سطح Database، Roleها، Permissionها، Schemaها و Context اجرای ماژول هر کدام مسئولیت جداگانه‌ای دارند. توابع امنیتی این مقاله برای مشاهده بخش‌هایی از همین مدل هستند و پاسخ یکسانی به سؤال «چه کسی در حال اجراست؟» نمی‌دهند.

در اتصال معمولی ممکن است نام Login و User شبیه باشد، ولی این شباهت یک الزام نیست. اعضای sysadmin در دیتابیس اغلب dbo دیده می‌شوند، contained user می‌تواند بدون Login کلاسیک کار کند و EXECUTE AS هویت مؤثر را عوض می‌کند. بنابراین طراحی Audit باید Login آغازکننده، Login مؤثر و User دیتابیس را جدا ثبت کند.

SID شناسه باینری هویت و principal_id شناسه عددی داخل Catalog مربوط است. توابع SUSER در سطح سرور و توابع USER در سطح دیتابیس معنا پیدا می‌کنند. در مهاجرت و بازیابی دیتابیس، درک SID برای جلوگیری از Orphaned User ضروری است؛ تکیه صرف بر نام یا عدد داخلی کافی نیست.

تشخیص هویت سطح دیتابیس

توابع این گروه باید با توجه به Scope و نوع شناسه انتخاب شوند. ثبت چند خروجی مکمل معمولاً تصویر مطمئن‌تری از Context امنیتی می‌سازد.

CURRENT_USER نام کاربر پایگاه‌داده در Context امنیتی جاری را برمی‌گرداند و با USER_NAME() هم‌ارز است. برخلاف ORIGINAL_LOGIN که Login اولیه اتصال را حفظ می‌کند، CURRENT_USER هویت مؤثر داخل دیتابیس را نشان می‌دهد. آموزش کامل CURRENT_USER با مثال‌های عملی

SESSION_USER نام کاربر پایگاه‌داده برای Context امنیتی جاری نشست را با نحو استاندارد ANSI برمی‌گرداند. از نظر نتیجه معمولاً با CURRENT_USER و USER_NAME() هم‌جهت است، ولی Login سطح سرور را نباید از آن استنباط کرد. آموزش کامل SESSION_USER با مثال‌های عملی

USER_ID شناسه عددی Database Principal متناظر با نام User را در پایگاه‌داده جاری برمی‌گرداند. USER_ID در محدوده دیتابیس است؛ SUSER_ID شناسه Principal سطح سرور را بررسی می‌کند و این دو قابل جایگزینی نیستند. آموزش کامل USER_ID با مثال‌های عملی

USER_NAME نام Database User متناظر با شناسه عددی را برمی‌گرداند و بدون آرگومان نام کاربر جاری را ارائه می‌کند. USER_NAME() با CURRENT_USER هم‌ارز است؛ SUSER_SNAME() نام Login سطح سرور را هدف می‌گیرد. آموزش کامل USER_NAME با مثال‌های عملی

تشخیص Login اولیه و مؤثر

توابع این گروه باید با توجه به Scope و نوع شناسه انتخاب شوند. ثبت چند خروجی مکمل معمولاً تصویر مطمئن‌تری از Context امنیتی می‌سازد.

ORIGINAL_LOGIN نام Login اولیه‌ای را برمی‌گرداند که نشست SQL Server را ایجاد کرده است، حتی اگر Context بعداً تغییر کند. SUSER_SNAME() هویت Login مؤثر جاری را نشان می‌دهد اما ORIGINAL_LOGIN() مبدأ نشست را نگه می‌دارد. آموزش کامل ORIGINAL_LOGIN با مثال‌های عملی

SYSTEM_USER نام Context امنیتی جاری را بدون پرانتز برمی‌گرداند و برای شناسایی هویت مؤثر اتصال به‌کار می‌رود. برای حفظ Login آغازکننده پس از جعل هویت از ORIGINAL_LOGIN() استفاده کنید؛ SYSTEM_USER هویت مؤثر جاری را هدف می‌گیرد. آموزش کامل SYSTEM_USER با مثال‌های عملی

نگاشت شناسه‌های سطح سرور

توابع این گروه باید با توجه به Scope و نوع شناسه انتخاب شوند. ثبت چند خروجی مکمل معمولاً تصویر مطمئن‌تری از Context امنیتی می‌سازد.

SUSER_ID شناسه عددی Server Principal متناظر با نام Login را برمی‌گرداند و بدون آرگومان Context جاری را بررسی می‌کند. SUSER_ID با شناسه عددی server_principal_id کار می‌کند؛ SUSER_SID شناسه باینری و پایدارتر SID را ارائه می‌دهد. آموزش کامل SUSER_ID با مثال‌های عملی

SUSER_NAME نام Login متناظر با شناسه عددی Server Principal را برمی‌گرداند و بدون آرگومان نام Context جاری را ارائه می‌کند. SUSER_NAME شناسه عددی می‌پذیرد، در حالی که SUSER_SNAME برای تبدیل SID باینری به نام طراحی شده است. آموزش کامل SUSER_NAME با مثال‌های عملی

SUSER_SID SID باینری Login مشخص‌شده یا Context امنیتی جاری را برمی‌گرداند. برخلاف SUSER_ID که شناسه عددی داخلی نمونه است، SID برای نگاشت هویت میان Metadata امنیتی اهمیت بیشتری دارد. آموزش کامل SUSER_SID با مثال‌های عملی

SUSER_SNAME نام Login متناظر با SID باینری را برمی‌گرداند و بدون آرگومان نام Context امنیتی جاری را نمایش می‌دهد. SUSER_SNAME ورودی باینری SID می‌گیرد؛ SUSER_NAME ورودی عددی server_principal_id را تبدیل می‌کند. آموزش کامل SUSER_SNAME با مثال‌های عملی

جدول مقایسه توابع

تابعکاربرد اصلینوع خروجی یا نکته مهملینک آموزش کامل
CURRENT_USERکنترل مجوزهای سطح دیتابیس، ثبت کاربر مؤثر و عیب‌یابی EXECUTE AS USERnvarchar(128)؛ Scope: پایگاه‌دادهمطالعه CURRENT_USER
ORIGINAL_LOGINممیزی غیرقابل‌ابهام، تشخیص آغازکننده واقعی عملیات و بررسی زنجیره‌های EXECUTE ASsysname؛ Scope: سرور و نشستمطالعه ORIGINAL_LOGIN
SESSION_USERکدهای قابل‌انتقال ANSI، سیاست‌های سطح سطر و ثبت کاربر مؤثر دیتابیسnvarchar(128)؛ Scope: پایگاه‌دادهمطالعه SESSION_USER
SUSER_IDاتصال نام Login به sys.server_principals، گزارش امنیتی و اعتبارسنجی Principalهای سطح سرورint؛ Scope: سرورمطالعه SUSER_ID
SUSER_NAMEخواناسازی شناسه‌های امنیتی در گزارش‌ها و تبدیل server_principal_id به نام قابل فهمnvarchar(128)؛ Scope: سرورمطالعه SUSER_NAME
SUSER_SIDتطبیق Login و User، انتقال دیتابیس، تشخیص Orphaned User و ممیزی بر پایه شناسه باینریvarbinary(85)؛ Scope: سرورمطالعه SUSER_SID
SUSER_SNAMEترجمه SID به نام، تحلیل Audit، بررسی sys.server_principals و عیب‌یابی نگاشت هویتnvarchar(128)؛ Scope: سرورمطالعه SUSER_SNAME
SYSTEM_USERثبت هویت جاری در Audit، Default Constraintها و گزارش عیب‌یابی نشستnvarchar(128)؛ Scope: سرور و نشستمطالعه SYSTEM_USER
USER_IDاتصال نام User به sys.database_principals، بررسی مالکیت و تولید گزارش مجوزهای دیتابیسint؛ Scope: پایگاه‌دادهمطالعه USER_ID
USER_NAMEخواناسازی principal_id، گزارش مجوزها، نمایش مالک اشیا و تحلیل Context سطح دیتابیسnvarchar(128)؛ Scope: پایگاه‌دادهمطالعه USER_NAME

مثال‌های ترکیبی و عملی

مثال 1: مقایسه سه لایه هویت

این Query یک سناریوی مستقل و قابل اجرا برای فهم مرزهای امنیتی ارائه می‌کند. خروجی واقعی به نوع احراز هویت، Principalهای موجود و مجوز مشاهده Metadata وابسته است.

SELECT ORIGINAL_LOGIN() AS OriginalLogin,
       SUSER_SNAME() AS EffectiveLogin,
       CURRENT_USER AS DatabaseUser;
نتیجه مورد انتظارنکته
نام اولیه، نام مؤثر و User دیتابیسنام‌ها و شناسه‌ها را در Context همان اتصال تفسیر کنید.

در پروژه واقعی، زمان UTC، شناسه نشست، نام برنامه و شناسه عملیات کسب‌وکار را نیز کنار داده امنیتی ثبت کنید.

مثال 2: نگاشت Login جاری به SID و برگشت

این Query یک سناریوی مستقل و قابل اجرا برای فهم مرزهای امنیتی ارائه می‌کند. خروجی واقعی به نوع احراز هویت، Principalهای موجود و مجوز مشاهده Metadata وابسته است.

DECLARE @Sid varbinary(85)=SUSER_SID();
SELECT @Sid AS LoginSid,SUSER_SNAME(@Sid) AS LoginName;
نتیجه مورد انتظارنکته
SID باینری و نام Login متناظرنام‌ها و شناسه‌ها را در Context همان اتصال تفسیر کنید.

در پروژه واقعی، زمان UTC، شناسه نشست، نام برنامه و شناسه عملیات کسب‌وکار را نیز کنار داده امنیتی ثبت کنید.

مثال 3: نگاشت User جاری به شناسه و برگشت

این Query یک سناریوی مستقل و قابل اجرا برای فهم مرزهای امنیتی ارائه می‌کند. خروجی واقعی به نوع احراز هویت، Principalهای موجود و مجوز مشاهده Metadata وابسته است.

DECLARE @Id int=USER_ID();
SELECT @Id AS UserId,USER_NAME(@Id) AS DatabaseUser;
نتیجه مورد انتظارنکته
شناسه عددی و نام Userنام‌ها و شناسه‌ها را در Context همان اتصال تفسیر کنید.

در پروژه واقعی، زمان UTC، شناسه نشست، نام برنامه و شناسه عملیات کسب‌وکار را نیز کنار داده امنیتی ثبت کنید.

مثال 4: ثبت رخداد ممیزی نمونه

این Query یک سناریوی مستقل و قابل اجرا برای فهم مرزهای امنیتی ارائه می‌کند. خروجی واقعی به نوع احراز هویت، Principalهای موجود و مجوز مشاهده Metadata وابسته است.

DECLARE @Audit TABLE
(OriginalLogin sysname,EffectiveLogin sysname,DatabaseUser sysname,CapturedAt datetime2);
INSERT @Audit
SELECT ORIGINAL_LOGIN(),SUSER_SNAME(),CURRENT_USER,SYSDATETIME();
SELECT * FROM @Audit;
نتیجه مورد انتظارنکته
یک رخداد کامل ممیزینام‌ها و شناسه‌ها را در Context همان اتصال تفسیر کنید.

در پروژه واقعی، زمان UTC، شناسه نشست، نام برنامه و شناسه عملیات کسب‌وکار را نیز کنار داده امنیتی ثبت کنید.

مثال 5: بررسی Permission به‌جای نام

این Query یک سناریوی مستقل و قابل اجرا برای فهم مرزهای امنیتی ارائه می‌کند. خروجی واقعی به نوع احراز هویت، Principalهای موجود و مجوز مشاهده Metadata وابسته است.

SELECT IS_ROLEMEMBER(N'db_datareader') AS IsReader,
       HAS_PERMS_BY_NAME(DB_NAME(),N'DATABASE',N'SELECT') AS HasSelect;
نتیجه مورد انتظارنکته
وضعیت Role و مجوز واقعینام‌ها و شناسه‌ها را در Context همان اتصال تفسیر کنید.

در پروژه واقعی، زمان UTC، شناسه نشست، نام برنامه و شناسه عملیات کسب‌وکار را نیز کنار داده امنیتی ثبت کنید.

مثال 6: گزارش نگاشت Principalهای دیتابیس

این Query یک سناریوی مستقل و قابل اجرا برای فهم مرزهای امنیتی ارائه می‌کند. خروجی واقعی به نوع احراز هویت، Principalهای موجود و مجوز مشاهده Metadata وابسته است.

SELECT dp.principal_id,dp.name,dp.type_desc,dp.sid,
       SUSER_SNAME(dp.sid) AS MappedLogin
FROM sys.database_principals AS dp
WHERE dp.principal_id>4
ORDER BY dp.name;
نتیجه مورد انتظارنکته
Principalهای دیتابیس و Login قابل نگاشتنام‌ها و شناسه‌ها را در Context همان اتصال تفسیر کنید.

در پروژه واقعی، زمان UTC، شناسه نشست، نام برنامه و شناسه عملیات کسب‌وکار را نیز کنار داده امنیتی ثبت کنید.

طراحی ممیزی و کنترل دسترسی

Audit خوب فقط نام کاربر را ذخیره نمی‌کند. حداقل Login اولیه، Login مؤثر، User دیتابیس، زمان UTC، SPID، نام برنامه، عملیات، شیء هدف و نتیجه موفق یا ناموفق ثبت می‌شود. داده ممیزی باید Append-only، محدود و دارای سیاست نگهداری مشخص باشد.

توابع هویتی ابزار مشاهده‌اند، نه موتور مجوزدهی. تصمیم دسترسی با GRANT، DENY، Role، Row-Level Security، Dynamic Data Masking در جای درست، مالکیت و Module Signing پیاده می‌شود. مقایسه مستقیم نام admin یا dbo هم شکننده است و هم اصل حداقل دسترسی را نقض می‌کند.

برای Connection Pooling باید تفاوت نشست فیزیکی و درخواست منطقی را در نظر گرفت. هویت کاربر برنامه ممکن است در Token یا جدول نشست برنامه باشد، در حالی که همه درخواست‌ها با یک Login سرویس به SQL Server می‌رسند. این دو هویت باید جدا و قابل پیوند ثبت شوند.

کارایی، پایش و بهترین روش‌ها

توابع امنیتی معمولاً سبک هستند، ولی تکرار آن‌ها روی میلیون‌ها ردیف، تبدیل ضمنی و Predicate غیرقابل Seek هزینه ایجاد می‌کند. مقادیر ثابت نشست را یک‌بار محاسبه کنید و روی ستون ایندکس‌شده تابع قرار ندهید.

Actual Execution Plan، STATISTICS IO و TIME، Query Store و Extended Events برای اندازه‌گیری پیش و پس از تغییر مناسب‌اند. آزمون باید با حجم داده، پارامتر و سطح هم‌زمانی نزدیک به تولید انجام شود و فقط زمان نمایش‌داده‌شده در SSMS معیار تصمیم نباشد.

  • Login، User، SID و principal_id را یک مفهوم فرض نکنید.
  • ORIGINAL_LOGIN و هویت مؤثر را جدا ثبت کنید.
  • NULL و محدودیت Metadata Visibility را پوشش دهید.
  • مجوز را بر پایه Role و Permission اعمال کنید.
  • Audit را در برابر تغییر غیرمجاز محافظت کنید.
  • رفتار Azure SQL و EXECUTE AS را جدا آزمایش کنید.

سؤالات متداول

پرسش 1: این تابع دقیقاً چه مسئله‌ای را حل می‌کند؟

هویت یا شناسه امنیتی مرتبط با Context اجرا را به‌شکل استاندارد SQL Server در اختیار Query می‌گذارد. نتیجه برای عیب‌یابی، Audit و گزارش مجوزها ارزشمند است، اما به‌تنهایی جایگزین کنترل Permission، Role و سیاست حداقل دسترسی نیست. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 2: برای شروع یادگیری این تابع چه پیش‌نیازی لازم است؟

شناخت تفاوت Login سطح سرور، User سطح دیتابیس، SID، Context نشست و دستور EXECUTE AS ضروری است. تمرین روی یک Instance آزمایشی با چند Login و User باعث می‌شود تفاوت خروجی‌ها به‌صورت عملی و بدون خطر برای محیط تولید دیده شود. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 3: آیا استفاده از این تابع در پروژه‌های تجاری مفید است؟

بله، به‌ویژه در سامانه‌های چندکاربره، پنل‌های مدیریتی و فرایندهای ممیزی. ارزش تجاری زمانی ایجاد می‌شود که خروجی تابع همراه زمان، نشست، نام برنامه، عملیات و شناسه رکورد ثبت شود تا تحلیل رخداد و پاسخ‌گویی ممکن باشد. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 4: برای طراحی Audit سازمانی با این تابع چه روشی مناسب است؟

ابتدا نیازهای حقوقی و عملیاتی تعیین و سپس هویت اولیه و مؤثر، زمان UTC، شناسه نشست و جزئیات عملیات ثبت شود. در پروژه‌های حساس، بازبینی معماری امنیت، مشاوره SQL Server و آزمون نفوذ مجوزها پیش از انتشار توصیه می‌شود. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 5: این تابع با توابع مشابه چه تفاوتی دارد؟

مرز اصلی در Scope و نوع شناسه است: برخی توابع Login سطح سرور، برخی User سطح دیتابیس و برخی SID یا شناسه عددی را برمی‌گردانند. انتخاب درست باید بر پایه سؤال دقیق کسب‌وکار باشد، نه شباهت ظاهری نام توابع. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 6: آیا می‌توان از نتیجه تابع در Trigger یا Stored Procedure استفاده کرد؟

از نظر فنی در بسیاری از سناریوها بله، اما باید رفتار مالکیت، EXECUTE AS، ماژول امضاشده و Connection Pooling آزمایش شود. پیش از پیاده‌سازی تراکنشی، نوع و طول ستون Audit و سیاست خطا نیز مشخص شود تا عملیات اصلی مختل نشود. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 7: رایج‌ترین خطا هنگام استفاده از این تابع چیست؟

رایج‌ترین خطا یکی دانستن Login و Database User و سپس اعطای دسترسی بر پایه مقایسه یک رشته است. خطای دیگر نادیده گرفتن NULL، Metadata Visibility و Context جانشین است. ثبت خروجی توابع مکمل به تشخیص علت کمک می‌کند. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 8: آیا فراخوانی این تابع باعث افت کارایی می‌شود؟

یک فراخوانی معمولاً سبک است، اما تکرار غیرضروری در میلیون‌ها ردیف یا قرار دادن تبدیل روی ستون ایندکس‌شده می‌تواند هزینه بسازد. مقدار ثابت نشست را یک‌بار در متغیر بگیرید و Predicate را SARGable نگه دارید. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 9: بهترین روش امنیتی برای استفاده از نتیجه چیست؟

نتیجه را برای مشاهده و ممیزی به‌کار ببرید و تصمیم مجوز را به Role، GRANT، DENY، Row-Level Security یا ماژول امضاشده بسپارید. داده ممیزی باید حداقل دسترسی، نگهداری مشخص و محافظت در برابر تغییر داشته باشد. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

پرسش 10: سازگاری تابع در نسخه‌های SQL Server و Azure چگونه است؟

هسته تابع در نسخه‌های رایج پشتیبانی می‌شود، اما Azure SQL Database، Managed Instance، Fabric و Synapse در Metadata سطح سرور یا EXECUTE AS تفاوت دارند. پیش از مهاجرت، مستندات نسخه هدف و تست خودکار سازگاری بررسی شود. انتخاب تابع مناسب با تعیین Scope سرور یا دیتابیس و نوع خروجی آغاز می‌شود.

سؤالات مصاحبه

سؤال مصاحبه 1: چرا CURRENT_USER و ORIGINAL_LOGIN ممکن است متفاوت باشند؟

اولی User مؤثر دیتابیس و دومی Login آغازکننده نشست است؛ نگاشت dbo یا EXECUTE AS اختلاف طبیعی ایجاد می‌کند.

سؤال مصاحبه 2: SID چه نقشی دارد؟

SID هویت Login و User را به هم مرتبط می‌کند و در مهاجرت برای جلوگیری از کاربر یتیم مهم است.

سؤال مصاحبه 3: چگونه Audit قابل اعتماد طراحی می‌کنید؟

چند لایه هویت، زمان UTC، نشست، عملیات و نتیجه را ثبت و داده را در برابر تغییر محافظت می‌کنم.

سؤال مصاحبه 4: نام کاربر یا Permission؛ کدام برای مجوز؟

Permission و Role معیار مجوز هستند؛ نام صرفاً داده مشاهده و ممیزی است.

سؤال مصاحبه 5: چگونه عملکرد را می‌سنجید؟

Plan واقعی، IO، CPU، مدت، Query Store و بار هم‌زمان را پیش و پس از تغییر مقایسه می‌کنم.

جمع‌بندی و مسیر مطالعه

توابع امنیتی SQL Server زمانی درست استفاده می‌شوند که Scope، Context و نوع Principal روشن باشد. برای Audit، هویت اولیه و مؤثر را جدا ثبت کنید؛ برای مجوز از Permission و Role بهره بگیرید؛ برای مهاجرت SID را جدی بگیرید و تفاوت سرویس‌های ابری را آزمایش کنید.

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620