- Four CAs Have Been Compromised Since June | Soulskill | rss.slashdot.org
- Microsoft® SQL Server® 2008 R2 Feature Pack | www.microsoft.com
- پشتیبانی از LocalDB در نگارش جدید دات نت 4.0.2 | blogs.msdn.com
SQLServerAgent could not be started (reason: Unable to connect to server '(local)'; SQLServerAgent cannot start).
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\SQLServerAgent
C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Log\SQLAGENT.OUT
2013-01-28 20:02:34 - ! [298] SQLServer Error: 780, SQL Server Network Interfaces: The logon attempt failed [SQLSTATE HY000] 2013-01-28 20:02:34 - ! [298] SQLServer Error: 780, Cannot generate SSPI context [SQLSTATE HY000] 2013-01-28 20:02:34 - ! [000] Unable to connect to server ; SQLServerAgent cannot start 2013-01-28 20:02:34 - ! [298] SQLServer Error: 780, SQL Server Network Interfaces: The logon attempt failed [SQLSTATE HY000] 2013-01-28 20:02:34 - ! [298] SQLServer Error: 780, Cannot generate SSPI context [SQLSTATE HY000] 2013-01-28 20:02:34 - ! [382] Logon to server failed (DisableAgentXPs) 2013-01-28 20:02:34 - ? [098] SQLServerAgent terminated (normally)
SQL Configuration manager -> SQL Server Agent -> Logon User -> NT/Local Service
در بسیاری موارد (مانند سیستمهای Multi Tenant) لازم هست تا مانع از این شویم که دادههای کاربران با هم تداخل پیدا کند و یا آنها بتوانند به دادههای هم دسترسی داشته باشند. مثلا میخواهیم کاربران هر شعبه از سازمان، تنها به اطلاعات شعبه خودشان دسترسی داشته باشند. یک کار ساده، پردردسر و بسیار بد آن است که از برنامه نویسها بخواهیم در هر کوئری عبارتی را اضافه کنند که سطح دسترسی را چک کند. اما اگر برنامه نویس جایی فراموش کرد چی؟ اگر سیاست دسترسی پیچیدهتر بود و مبنی بر پارامترهای مختلف محاسبه میشد چه خواهد شد؟ این راهکار در حجم بزرگ غیر مطمئن و غیرقابل نگهداری است.
در EF6 قابلیتی به نام Interception وجود دارد که با استفاده از آن میتوان سیاست دسترسی به داده را در لایههای پایینی طراحی کرد. در این روش برنامه نویس لایه هایی بالا، بدون آنکه درگیر مفاهیمی مانند Tenant و سیاستها بشود، میتواند به راحتی کوئری هایش را تولید کند. سپس EF به طور خودکار تغییری در کوئریها خواهد داد تا دسترسیهای لازم رعایت کرده باشد. برای اینکار میتوانید از کتابخانه EntityFramework.DynamicFilters استفاده کنید.
این روش هم علی رغم همه مزایا معایبی هم دارد. اگر بخواهیم از همین پایگاه داده استفاده کنیم ولی در محیط دات نت نباشیم و یا از EF6 استفاده نکنیم، دوباره مشکلات اغاز میشوند. سیاستها را باید در همه جا کپی کنیم و در صورت لزوم هم، مجددا همه را تغییر دهیم.
در SQL Server 2016 قابلیتی به نام Row Level Security وجود دارد، که به ما اجازه میدهد سیاستهای دسترسی با داده را در لایه پایگاه داده متمرکز کنیم. در این صورت اپلیکشنها هیچگونه آگاهی ایی نسبت به سیاستها نخواهند داشت و درگیر این مفاهیم در سطح کد نخواهیم بود. همچنین در صورت لزوم به تغییر سیاست ها، فقط لازم است تغییراتی را در پایگاه داده بدهیم. با این روش، به هر طریقی و از هر ابزاری که به پایگاه داده کوئری هایمان را ارسال کنیم، سیاستهای دسترسی به داده اعمال خواهند شد و امنیت بالا و البته ریزدانه ای (granular) را خواهیم داشت.
در مثال زیر خواهیم دید که چگونه میتوان با استفاده از EF6 از ویژگی RLS بهره برد. این مثال یکی دیگر از کاربردهای Interception را نیز توضیح میدهد.
دستورات زیر در صورتی که در خارج از تریگر فراخوانی بشن عملکردشون درسته ، اما در تریگر خطا میدن :
-- Insert -- INSERT INTO OPENQUERY(MyLinkServer, 'SELECT * FROM unit') VALUES ( 1, 5, 'fa', '0', GETDATE(), '1', GETDATE(), '1' ); ---------------------------------------------------------------------------------------- -- Update -- --1 UPDATE OPENQUERY(MyLinkServer , 'SELECT * FROM unit WHERE id=4') SET [is_deleted] = '0'; --2 EXEC('UPDATE unit set is_deleted=''1'' where id=4;') AT MyLinkServer ; -- 3 UPDATE OPENQUERY(MyLinkServer , 'SELECT * FROM unit') SET [is_deleted] = '0' WHERE id = 4; ---------------------------------------------------------------------------------------- -- Delete -- DELETE OPENQUERY(MyLinkServer, 'select * from unit where id=4;');