آموزش تابع SUSER_NAME در SQL Server
این راهنما تابع SUSER_NAME را از مفهوم پایه تا کاربرد سازمانی بررسی میکند. برای مشاهده جایگاه این تابع در کنار سایر ابزارهای هویتی، راهنمای جامع توابع امنیتی SQL Server را نیز مطالعه کنید.
مقدمه
در SQL Server هر اتصال فقط یک نام ساده نیست؛ Login در سطح Instance، User در سطح Database، SID، شناسه عددی Principal و Context مؤثر اجرا لایههای جداگانهای هستند. تابع SUSER_NAME برای پاسخ دادن به بخشی مشخص از این مدل طراحی شده است و نام Login متناظر با شناسه عددی Server Principal را برمیگرداند و بدون آرگومان نام Context جاری را ارائه میکند.
کاربرد اصلی آن شامل خواناسازی شناسههای امنیتی در گزارشها و تبدیل server_principal_id به نام قابل فهم است. با این حال، خروجی تابع باید همراه نام دیتابیس، شناسه نشست، زمان و توابع مکمل تفسیر شود. ثبت یک نام بدون Context میتواند در زمان جعل هویت، اجرای ماژول با مالک متفاوت یا استفاده از Connection Pooling به برداشت نادرست منجر شود.
این مقاله مثالها را از فراخوانی پایه شروع میکند و سپس به گزارشگیری از Catalog Viewها، مدیریت NULL، ممیزی، خطای رایج و الگوی بهینه میرسد. همه Queryها برای Microsoft SQL Server نوشته شدهاند؛ عملیات وابسته به مجوز ممکن است در محیط محدود پیام کمبود دسترسی برگرداند.
تعریف، نحو و خروجی
نام Login متناظر با شناسه عددی Server Principal را برمیگرداند و بدون آرگومان نام Context جاری را ارائه میکند. محدوده معنایی این تابع «سرور» است؛ بنابراین نباید نتیجه آن را خودکار به Principal لایه دیگر تعمیم داد.
نحو تابع
SELECT SUSER_NAME ( [ server_user_id ] ) AS SecurityValue;
پارامترها
- نحو رسمی: SUSER_NAME ( [ server_user_id ] )
- آرگومان اختیاری، اگر وجود داشته باشد، باید از نوع سازگار با نام یا شناسه همان سطح باشد.
- برای ورودی نامعتبر یا Principal غیرقابل مشاهده، NULL را بهعنوان یک حالت واقعی مدیریت کنید.
نوع خروجی
نوع خروجی مستند تابع nvarchar(128) است. پیش از ذخیرهسازی، ستون مقصد را با همین نوع یا یک تبدیل آگاهانه تعریف کنید تا بریدگی متن، تبدیل ضمنی و از دست رفتن SID رخ ندهد.
تفاوت مهم با تابع نزدیک چنین است: SUSER_NAME شناسه عددی میپذیرد، در حالی که SUSER_SNAME برای تبدیل SID باینری به نام طراحی شده است. نکته عملی نیز این است که در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند.
مدل امنیتی و تفسیر درست نتیجه
Login اجازه ورود به موتور یا سرویس را مدل میکند، ولی Database User نماینده همان هویت یا یک هویت مستقل در دیتابیس است. نگاشت این دو معمولاً با SID انجام میشود. در نتیجه، مساوی بودن نامها یک قرارداد رایج است و تضمین معماری محسوب نمیشود.
هنگام استفاده از SUSER_NAME ابتدا مشخص کنید سؤال شما درباره آغازکننده اتصال، Context مؤثر Login، User جاری دیتابیس، شناسه عددی یا SID است. سپس تابعی را انتخاب کنید که دقیقاً همان لایه را پوشش دهد و خروجی را کنار ORIGINAL_LOGIN()، SUSER_SNAME() و CURRENT_USER مقایسه کنید.
در سامانههای حرفهای، نتیجه یک تابع امنیتی نباید مستقیماً نقش مجوزدهنده داشته باشد. کنترل دسترسی با GRANT و DENY، Roleها، Row-Level Security، مالکیت و Module Signing انجام میشود؛ تابع هویتی بیشتر برای مشاهده، Audit، برچسبگذاری و عیبیابی است.
مثالهای عملی مستقل
مثال 1: فراخوانی پایه و مشاهده هویت جاری
در این سناریو هدف آن است که رفتار SUSER_NAME در «فراخوانی پایه و مشاهده هویت جاری» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
SELECT SUSER_NAME() AS [SUSER_NAME_Result];
| خروجی | تفسیر |
|---|
| یک نام یا شناسه وابسته به Context جاری | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
سادهترین آزمون برای شناخت نتیجه تابع در همان اتصال است. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 2: ثبت نتیجه همراه با مشخصات نشست
در این سناریو هدف آن است که رفتار SUSER_NAME در «ثبت نتیجه همراه با مشخصات نشست» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
SELECT
@@SPID AS SessionId,
DB_NAME() AS DatabaseName,
SUSER_NAME() AS SecurityValue,
SYSDATETIMEOFFSET() AS CapturedAt;
| خروجی | تفسیر |
|---|
| یک ردیف شامل نشست، دیتابیس، مقدار امنیتی و زمان | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
قرار دادن Context کنار نتیجه، شواهد ممیزی را قابل تفسیر میکند. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 3: تبدیل و ذخیره نتیجه در متغیر یا جدول
در این سناریو هدف آن است که رفتار SUSER_NAME در «تبدیل و ذخیره نتیجه در متغیر یا جدول» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
DECLARE @Id int=SUSER_ID();
SELECT @Id AS PrincipalId,SUSER_NAME(@Id) AS LoginName;
| خروجی | تفسیر |
|---|
| شناسه و نام Login جاری | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
این الگو نتیجه تابع را یکبار محاسبه میکند و برای ثبت Audit یا ادامه پردازش آماده نگه میدارد. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 4: استفاده در شرط امنیتی کنترلشده
در این سناریو هدف آن است که رفتار SUSER_NAME در «استفاده در شرط امنیتی کنترلشده» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
SELECT
CASE
WHEN SUSER_NAME() IS NULL THEN N'هویت قابل تشخیص نیست'
ELSE N'هویت شناسایی شد'
END AS SecurityCheck;
| خروجی | تفسیر |
|---|
| پیام وضعیت شناسایی هویت | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
وجود مقدار بهتنهایی مجوز ایجاد نمیکند؛ تصمیم دسترسی باید بر پایه Role و Permission باشد. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 5: مقایسه هویت اولیه و هویت مؤثر
در این سناریو هدف آن است که رفتار SUSER_NAME در «مقایسه هویت اولیه و هویت مؤثر» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
SELECT
ORIGINAL_LOGIN() AS OriginalLogin,
SUSER_SNAME() AS EffectiveLogin,
CURRENT_USER AS DatabaseUser,
CONVERT(nvarchar(128),SUSER_NAME()) AS FunctionValue;
| خروجی | تفسیر |
|---|
| چهار ستون برای تشخیص اختلاف Context | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
این مقایسه مرز Login سطح سرور و User سطح دیتابیس را روشن و جعل هویت را آشکار میکند. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 6: مدیریت ورودی یا خروجی NULL
در این سناریو هدف آن است که رفتار SUSER_NAME در «مدیریت ورودی یا خروجی NULL» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
DECLARE @Id int=NULL;
SELECT CASE WHEN @Id IS NULL THEN NULL ELSE SUSER_NAME(@Id) END AS SafeValue;
| خروجی | تفسیر |
|---|
| NULL یا مقدار جایگزین کنترلشده | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
کنترل صریح NULL مانع تصمیم اشتباه و ثبت داده مبهم در فرایندهای امنیتی میشود. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 7: بررسی حالت مرزی و Context جانشین
در این سناریو هدف آن است که رفتار SUSER_NAME در «بررسی حالت مرزی و Context جانشین» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
SELECT TOP (10)
principal_id,
name,
type_desc,
CONVERT(nvarchar(128),SUSER_NAME()) AS ResolvedValue
FROM sys.database_principals
WHERE principal_id>4
ORDER BY principal_id;
| خروجی | تفسیر |
|---|
| حداکثر ده Principal و مقدار تبدیلشده | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
حالتهای مرزی باید در محیط آزمایشی و با کمترین سطح دسترسی لازم بررسی شوند. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 8: گزارش سازمانی از کاتالوگهای امنیتی
در این سناریو هدف آن است که رفتار SUSER_NAME در «گزارش سازمانی از کاتالوگهای امنیتی» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
SELECT TOP (20)
sp.name,sp.type_desc,sp.is_disabled,
CONVERT(nvarchar(128),SUSER_NAME()) AS CurrentContextValue
FROM sys.server_principals AS sp
WHERE sp.type IN ('S','U','G','E','X')
ORDER BY sp.name;
| خروجی | تفسیر |
|---|
| فهرست Principalها همراه با Context اجرای گزارش | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
ترکیب تابع با Catalog View برای گزارش دسترسی مناسب است؛ مشاهده Metadata همچنان تابع مجوز اجراکننده است. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 9: روش اشتباه و نسخه اصلاحشده
در این سناریو هدف آن است که رفتار SUSER_NAME در «روش اشتباه و نسخه اصلاحشده» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
-- روش اشتباه: اعطای مجوز فقط با مقایسه متن نام
-- IF CONVERT(nvarchar(128),SUSER_NAME())=N'admin' SELECT N'مجاز';
-- روش صحیح: بررسی عضویت Role و مجوز واقعی
SELECT
IS_ROLEMEMBER(N'db_datareader') AS IsDataReader,
HAS_PERMS_BY_NAME(DB_NAME(),N'DATABASE',N'SELECT') AS HasSelectPermission;
| خروجی | تفسیر |
|---|
| صفر، یک یا NULL برای وضعیت Role و Permission | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
نام هویت داده ممیزی است؛ مجوز واقعی باید با سازوکار Role و Permission ارزیابی شود. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
مثال 10: الگوی کارایی با محاسبه یکباره
در این سناریو هدف آن است که رفتار SUSER_NAME در «الگوی کارایی با محاسبه یکباره» بهصورت مستقل دیده شود. Query را در یک پنجره جدا اجرا کنید و نتیجه را با نوع اتصال و Context امنیتی همان نشست تطبیق دهید.
DECLARE @SecurityValue nvarchar(128)=CONVERT(nvarchar(128),SUSER_NAME());
SELECT o.name,o.type_desc,@SecurityValue AS SecurityValue
FROM sys.objects AS o
WHERE o.object_id>0
AND o.name LIKE N'sp[_]%'
ORDER BY o.name;
| خروجی | تفسیر |
|---|
| اشیای منطبق و یک مقدار امنیتی ثابت برای Query | نتیجه واقعی تابع SUSER_NAME به Principalها و مجوزهای محیط وابسته است. |
در Queryهای بزرگ نتیجه ثابت نشست را یکبار محاسبه کنید؛ از قرار دادن تابع روی ستون فیلترشونده پرهیز کنید. این نمونه بهجای اتکا به یک مقدار از پیشفرضشده، معنای خروجی و محدودیت محیط اجرا را صریح نگه میدارد.
خطاهای رایج و روش رفع آنها
اولین خطا، تفسیر SUSER_NAME در Scope اشتباه است. اگر تابع در سطح دیتابیس معنا دارد، نتیجه آن نام Login سرور نیست؛ اگر در سطح سرور کار میکند، از آن نمیتوان عضویت Role دیتابیس را نتیجه گرفت. Scope را پیش از نوشتن شرط مشخص کنید.
دومین خطا، نادیده گرفتن EXECUTE AS و زنجیره مالکیت است. یک Stored Procedure ممکن است با Context دیگری اجرا شود، در حالی که Login اولیه نشست ثابت مانده است. ثبت همزمان ORIGINAL_LOGIN()، SUSER_SNAME() و CURRENT_USER اختلاف را آشکار میکند.
سومین خطا، فرض غیرممکن بودن NULL یا اتکا به مشاهده کامل Metadata است. Principal حذفشده، شناسه نامعتبر، محدودیت مجوز یا تفاوت سرویس ابری میتواند خروجی را تغییر دهد. برای NULL مسیر کنترلشده، هشدار و آزمون خودکار تعریف کنید.
نکات کارایی و بهینهسازی
فراخوانی منفرد SUSER_NAME معمولاً هزینه سنگینی ندارد؛ مشکل زمانی ایجاد میشود که همان مقدار ثابت نشست برای هر ردیف یک مجموعه بزرگ دوباره محاسبه یا به تبدیلهای زنجیرهای وارد شود. نتیجه را یکبار در متغیر با نوع مناسب ذخیره کنید.
در Predicateها تابع را روی ستون ایندکسشده اعمال نکنید. ابتدا مقدار امنیتی را به نوع ستون تبدیل و سپس ستون را مستقیماً با پارامتر مقایسه کنید. این الگو احتمال Seek، تخمین Cardinality بهتر و استفاده مجدد از Plan را افزایش میدهد.
برای ارزیابی واقعی از Actual Execution Plan، SET STATISTICS IO, TIME و Query Store استفاده کنید. قبل و بعد از تغییر را با داده و پارامتر مشابه اندازهگیری کنید؛ سریع بودن یک اجرای آزمایشی روی جدول کوچک معیار کافی برای محیط تولید نیست.
بهترین روشها
- Scope تابع و پرسش امنیتی را پیش از پیادهسازی مستند کنید.
- هویت اولیه و هویت مؤثر را در Audit از هم جدا نگه دارید.
- نتیجه را با نوع داده مناسب و بدون بریدگی ذخیره کنید.
- NULL و نبود مجوز مشاهده Metadata را مدیریت کنید.
- بهجای مقایسه نام، Permission و Role واقعی را بررسی کنید.
- برای عملیات حساس از کمترین سطح دسترسی و Module Signing بهره بگیرید.
- رفتار EXECUTE AS و REVERT را در تست خودکار پوشش دهید.
- تفاوت SQL Server، Azure SQL و Managed Instance را پیش از مهاجرت آزمایش کنید.
کاربردهای واقعی در پروژه
در سامانه مالی میتوان هویت اولیه اتصال و Context مؤثر را همراه شماره سند ثبت کرد تا تغییرات بعدی قابل پیگیری باشد. این داده باید فقط برای تیم مجاز قابل مشاهده و در برابر UPDATE یا DELETE غیرمجاز محافظت شود.
در یک پلتفرم چندمستاجری، تابع هویتی برای عیبیابی مفید است، اما Tenant از Claim یا جدول نگاشت معتبر استخراج میشود و Row-Level Security دسترسی ردیفی را اعمال میکند. آمیختن نام Login با شناسه مشتری یک ریسک طراحی است.
در پروژه مهاجرت، مقایسه SIDهای Login و User به کشف کاربران یتیم کمک میکند. تهیه گزارش قبل از Cutover، بازسازی Loginها با SID درست و آزمون مجوزهای مؤثر از قطعی سرویس و دسترسی بیش از حد جلوگیری میکند.
سؤالات متداول
پرسش 1: SUSER_NAME دقیقاً چه مسئلهای را حل میکند؟
هویت یا شناسه امنیتی مرتبط با Context اجرا را بهشکل استاندارد SQL Server در اختیار Query میگذارد. نتیجه برای عیبیابی، Audit و گزارش مجوزها ارزشمند است، اما بهتنهایی جایگزین کنترل Permission، Role و سیاست حداقل دسترسی نیست. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 2: برای شروع یادگیری SUSER_NAME چه پیشنیازی لازم است؟
شناخت تفاوت Login سطح سرور، User سطح دیتابیس، SID، Context نشست و دستور EXECUTE AS ضروری است. تمرین روی یک Instance آزمایشی با چند Login و User باعث میشود تفاوت خروجیها بهصورت عملی و بدون خطر برای محیط تولید دیده شود. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 3: آیا استفاده از SUSER_NAME در پروژههای تجاری مفید است؟
بله، بهویژه در سامانههای چندکاربره، پنلهای مدیریتی و فرایندهای ممیزی. ارزش تجاری زمانی ایجاد میشود که خروجی تابع همراه زمان، نشست، نام برنامه، عملیات و شناسه رکورد ثبت شود تا تحلیل رخداد و پاسخگویی ممکن باشد. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 4: برای طراحی Audit سازمانی با SUSER_NAME چه روشی مناسب است؟
ابتدا نیازهای حقوقی و عملیاتی تعیین و سپس هویت اولیه و مؤثر، زمان UTC، شناسه نشست و جزئیات عملیات ثبت شود. در پروژههای حساس، بازبینی معماری امنیت، مشاوره SQL Server و آزمون نفوذ مجوزها پیش از انتشار توصیه میشود. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 5: SUSER_NAME با توابع مشابه چه تفاوتی دارد؟
مرز اصلی در Scope و نوع شناسه است: برخی توابع Login سطح سرور، برخی User سطح دیتابیس و برخی SID یا شناسه عددی را برمیگردانند. انتخاب درست باید بر پایه سؤال دقیق کسبوکار باشد، نه شباهت ظاهری نام توابع. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 6: آیا میتوان از نتیجه تابع در Trigger یا Stored Procedure استفاده کرد؟
از نظر فنی در بسیاری از سناریوها بله، اما باید رفتار مالکیت، EXECUTE AS، ماژول امضاشده و Connection Pooling آزمایش شود. پیش از پیادهسازی تراکنشی، نوع و طول ستون Audit و سیاست خطا نیز مشخص شود تا عملیات اصلی مختل نشود. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 7: رایجترین خطا هنگام استفاده از SUSER_NAME چیست؟
رایجترین خطا یکی دانستن Login و Database User و سپس اعطای دسترسی بر پایه مقایسه یک رشته است. خطای دیگر نادیده گرفتن NULL، Metadata Visibility و Context جانشین است. ثبت خروجی توابع مکمل به تشخیص علت کمک میکند. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 8: آیا فراخوانی SUSER_NAME باعث افت کارایی میشود؟
یک فراخوانی معمولاً سبک است، اما تکرار غیرضروری در میلیونها ردیف یا قرار دادن تبدیل روی ستون ایندکسشده میتواند هزینه بسازد. مقدار ثابت نشست را یکبار در متغیر بگیرید و Predicate را SARGable نگه دارید. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 9: بهترین روش امنیتی برای استفاده از نتیجه چیست؟
نتیجه را برای مشاهده و ممیزی بهکار ببرید و تصمیم مجوز را به Role، GRANT، DENY، Row-Level Security یا ماژول امضاشده بسپارید. داده ممیزی باید حداقل دسترسی، نگهداری مشخص و محافظت در برابر تغییر داشته باشد. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
پرسش 10: سازگاری تابع در نسخههای SQL Server و Azure چگونه است؟
هسته تابع در نسخههای رایج پشتیبانی میشود، اما Azure SQL Database، Managed Instance، Fabric و Synapse در Metadata سطح سرور یا EXECUTE AS تفاوت دارند. پیش از مهاجرت، مستندات نسخه هدف و تست خودکار سازگاری بررسی شود. در مورد SUSER_NAME نیز باید محدودیت «در کد جدیدی که SID در اختیار دارد SUSER_SNAME انتخاب روشنتری است؛ شناسه نامعتبر میتواند NULL ایجاد کند» در آزمونها لحاظ شود.
سؤالات مصاحبه تخصصی
سؤال مصاحبه 1: تفاوت Login و User چیست؟
Login Principal سطح سرور برای ورود است و User Principal سطح دیتابیس برای مجوزهای همان دیتابیس. نگاشت معمولاً با SID انجام میشود و نام یکسان تضمینکننده یکسان بودن هویت نیست.
سؤال مصاحبه 2: SUSER_NAME چه Scope و خروجیای دارد؟
Scope آن سرور و نوع خروجی nvarchar(128) است. پاسخ کامل باید کاربرد، رفتار NULL، جعل هویت و تفاوت با تابع مشابه را نیز توضیح دهد.
سؤال مصاحبه 3: چرا ORIGINAL_LOGIN و SUSER_SNAME را همزمان ثبت میکنیم؟
اولی آغازکننده نشست و دومی Context مؤثر Login را نشان میدهد. اختلاف آنها میتواند اجرای EXECUTE AS LOGIN یا زنجیرهای از جعل هویت را مشخص کند.
سؤال مصاحبه 4: چگونه از افت کارایی جلوگیری میکنید؟
مقدار ثابت نشست را یکبار محاسبه، نوع داده را هماهنگ و Predicate را SARGable میکنم؛ سپس Plan واقعی، IO، CPU و Query Store را پیش و پس از تغییر مقایسه میکنم.
سؤال مصاحبه 5: آیا نام کاربر برای مجوزدهی کافی است؟
خیر. نام برای مشاهده مناسب است؛ مجوز باید با Role، Permission، RLS یا Module Signing اعمال شود و همه مسیرها با کمترین سطح دسترسی آزمون شوند.
چکلیست نهایی
- Scope سرور یا دیتابیس مشخص شد.
- نوع خروجی و ستون مقصد هماهنگ است.
- NULL و Principal نامعتبر پوشش داده شد.
- هویت اولیه و مؤثر جدا ثبت میشوند.
- مجوز بر پایه Role و Permission است.
- EXECUTE AS در تست وجود دارد.
- Plan و IO در بار واقعی اندازهگیری شده است.
- محدودیت نسخه مقصد بررسی شده است.
جمعبندی
تابع SUSER_NAME زمانی ارزش واقعی دارد که در مدل درست امنیت SQL Server تفسیر شود. نام Login متناظر با شناسه عددی Server Principal را برمیگرداند و بدون آرگومان نام Context جاری را ارائه میکند و برای خواناسازی شناسههای امنیتی در گزارشها و تبدیل server_principal_id به نام قابل فهم مناسب است. نتیجه باید همراه Context، زمان و توابع مکمل ثبت شود و هرگز بهتنهایی جایگزین کنترل مجوز نباشد.
برای مرور تفاوت همه توابع این مجموعه به مقاله مادر توابع امنیتی SQL Server بازگردید. در محیط تولید، ابتدا سناریوهای Login، User، SID، EXECUTE AS، NULL و Metadata Visibility را در محیط آزمایشی تکرار و سپس با پایش Query Store منتشر کنید.