دوره بررسی ASP.NET CORE Identity
ASP.NET CORE Identity Under the Hood | Authentication & Authorization | .NET 8
00:00:00 Introduction
00:04:31 1. Security Overview
00:10:34 2. Authentication and Authorization Flow
00:17:18 3. ASP.NET Core Basics
00:23:31 4. Security Context in ASP.NET Core
00:27:23 5. Anonymous Identity
00:33:26 6. Create a Login Page with Razor Pages
00:46:02 7. Generate Cookie with Cookie Authentication Handler
01:06:01 8. Authenticaiton Middle and Authentication Scheme
01:15:16 9. Authorization Architecture Flow
01:23:58 10. Simple Policy based Authorization
01:43:50 11. Login & Logout Partial View
01:52:56 12. Custom Policy based Authorization
02:05:11 13. Cookie Lifespan & Browser Session
با بالا رفتن تعداد اشیاء تعریف شده در SQL server ، نگهداری آنها نیز مشکلتر میشود. در این حالت تغییر کوچکی در یکی از اشیاء ممکن است باعث از کار افتادن قسمتی از سیستم شود. بنابراین قبل از هر گونه تغییری در یک شیء، ابتدا باید سایر اشیاء وابسته به آن را یافت و در نظر داشت ( dependencies ). برای این منظور ( impact analysis ) راهکارهای مختلفی در SQL server وجود دارد که در ادامه به آنها خواهیم پرداخت:
الف) استفاده از امکانات management studio (اس کیوال سرور 2005 به بعد)
سادهترین راه ممکن که گزارش مفصلی را نیز ارائه میدهد، کلیک بر روی یک شیء در management studio و انتخاب گزینه view dependencies است (شکل زیر).
در صفحه ظاهر شده میتوان اشیایی را که شیء مورد نظر به آنها وابسته است، مشاهده نمود یا برعکس (اشیایی که عملکرد آنها وابسته به شیء انتخابی است را نیز میتوان ملاحظه کرد).
ب) کوئری گرفتن از جداول سیستمی
امکانات قسمت قبل را با استفاده از اطلاعات جدول syscomments نیز میتوان شبیه سازی کرد. در این جدول اطلاعات تعاریف کلیه view ، trigger ، رویههای ذخیره شده و غیره نگهداری میشود. برای مثال فرض کنید قصد داریم در جدول Orders دیتابیس Northwind ، نام فیلد OrderDate را تغییر دهیم. قبل از اینکار بهتر است کوئری زیر را اجرا کنیم تا نام اشیاء وابسته را بدست آوریم:
SELECT NAME
FROM syscomments c
JOIN sysobjects o
ON c.id = o.id
WHERE TEXT LIKE '%OrderDate%'
AND TEXT LIKE '%Orders%'
این روش انعطاف پذیری بیشتری را نسبت به امکانات قسمت الف ، ارائه میدهد. برای نمونه فرض کنید میخواهید در یک دیتابیس کلیه اشیایی که عملیات delete را انجام میدهند پیدا کنید (جستجوی اشیاء حاوی یک عبارت خاص). در این مورد خواهیم داشت:
SELECT NAME
FROM syscomments c
JOIN Northwind.dbo.sysobjects o
ON c.id = o.id
WHERE TEXT LIKE '%delete%'
جدول سیستمی دیگری در اس کیوال سرور به نام sysdepends وجود دارد که اطلاعات وابستگیهای اشیاء در آنها نگهداری میشود. برای دسترسی به اطلاعات این جدول ، اس کیوال سرور رویه ذخیره شده سیستمی sp_depends را ارائه داده است. برای مثال فرض کنید میخواهیم لیست اشیایی را که به جدول Oredres دیتابیس Northwind وابسته هستند، پیدا کنیم. در این حالت داریم:
USE Northwind
EXEC sp_depends 'Orders'
د) استفاده از schema view
با استفاده از view سیستمی INFORMATION_SCHEMA.ROUTINES ، که از ترکیب جداول syscolumns و sysobjects ایجاد شده است نیز میتوان عملکرد sp_depends را شبیه سازی کرد اما جداول و view ها از گزارش آن حذف شدهاند.
SELECT routine_name,
routine_type
FROM INFORMATION_SCHEMA.ROUTINES
WHERE routine_definition LIKE '%Orders%'
ه) استفاده از برنامه SQL Dependency Tracker
نسخه آزمایشی برنامه ذکر شده را از این آدرس میتوان دریافت کرد.
همانطور که ملاحظه میکنید این جستجوها بر روی اطلاعات ذخیره شده در اس کیوال سرور صورت میگیرند و اگر در کدهای خود در خارج از اس کیوال سرور مخلوطی از عبارات اس کیوال را داشته باشید، نگهداری آنها بسیار مشکل خواهد بود. بنابراین تا حد ممکن باید عملیات مرتبط را در دیتابیس و توسط اشیاء اس کیوال سرور مانند رویههای ذخیره شده، view ها و امثال آنها انجام داد تا این جدا سازی بهخوبی صورت گرفته و در زمان نیاز به انجام تغییرات، ردگیری اشیاء وابسته بهسادگی صورت گیرد.
آیا جداول بهینه سازی شدهی برای حافظه، همان DBCC PINTABLE منسوخ شده هستند؟
در نگارشهای قدیمیتر اس کیوال سرور، دستوری وجود داشت به نام DBCC PINTABLE که سبب ثابت نگه داشتن صفحات جداول مبتنی بر دیسک یک دیتابیس، در حافظه میشد. به این ترتیب تمام خواندنهای مرتبط با آن جدول، از حافظه صورت میگرفت. مشکل این روش که سبب منسوخ شدن آن گردید، اثرات جانبی آن بود؛ مانند خوانده شدن صفحات جدیدتر (با توجه به اینکه ساختار پردازشی و موتور بانک اطلاعاتی تغییری نکرده بود) و نیاز به حافظهی بیشتر تا حدی که کل کش بافر سیستم را پر میکرد و امکان انجام سایر امور آن مختل میشدند. همچنین اولین ارجاعی به یک جدول، سبب قرار گرفتن کل آن در حافظه میگشت. به علاوه ساختار این سیستم نیز همانند روش مبتنی بر دیسک، بر اساس همان روشهای قفل گذاری، ذخیره سازی اطلاعات و تهیه ایندکسهای متداول بود.
اما جداول بهینه سازی شدهی برای حافظه، از یک موتور کاملا جدید استفاده میکنند؛ با ساختار جدیدی برای ذخیره سازی اطلاعات و تهیه ایندکسها. دسترسی به اطلاعات آنها شامل قفل گذاریهای متداول نیست و در آن حداقل زمان دسترسی به اطلاعات درنظر گرفته شدهاست. همچنین در آنها data pages یا index pages و کش بافر نیز وجود ندارد.
نحوهی ذخیره سازی و مدیریت اطلاعات جداول بهینه سازی شده برای حافظه
جداول بهینه سازی شده برای حافظه، فرمت ردیفهای کاملا جدیدی را نیز به همراه دارند و جهت قرارگرفتن در حافظه ودسترسی سریع به آنها بهینه سازی شدهاند. برخلاف جداول مبتنی بر دیسک سخت که اطلاعات آنها در یک سری صفحات خاص به نامهای data or index pages ذخیره میشوند، اینگونه جداول، دارای ظروف مبتنی بر صفحه نیستند و از مفهوم چند نگارشی برای ذخیره سازی اطلاعات استفاده میکنند؛ به این معنا که ردیفها به ازای هر تغییری، دارای یک نگارش جدید خواهند بود و بلافاصله در همان نگارش اصلی به روز رسانی نمیشوند.
در اینجا هر ردیف دارای یک timestamp شروع و یک timestamp پایان است. timestamp شروع بیانگر تراکنشی است که ردیف را ثبت کرده و timestamp پایان برای مشخص سازی تراکنشی بکار میرود که ردیف را حذف کرده است. اگر timestamp پایان، دارای مقدار بینهایت باشد، به این معنا است که ردیف متناظر با آن هنوز حذف نشدهاست. به روز رسانی یک ردیف در اینجا، ترکیبی است از حذف یک ردیف موجود و ثبت ردیفی جدید. برای یک عملیات فقط خواندنی، تنها نگارشهایی که timestamp معتبری داشته باشند، قابل مشاهده خواهند بود و از مابقی صرفنظر میگردد.
در OLTP درون حافظهای که از روش چندنگارشی همزمانی استفاده میکند، برای یک ردیف مشخص، ممکن است چندین نگارش وجود داشته باشند؛ بسته به تعداد باری که یک رکورد به روز رسانی شدهاست. در اینجا یک سیستم garbage collection همیشه فعال، نگارشهایی را که توسط هیچ تراکنشی مورد استفاده قرار نمیگیرند، به صورت خودکار حذف میکند؛ تا مشکل کمبود حافظه رخ ندهد.
آیا میتوان به کارآیی جداول بهینه سازی شده برای حافظه با همان روش متداول مبتنی بر دیسک اما با بکارگیری حافظهی بیشتر و استفاده از یک SSD RAID رسید؟
خیر! حتی اگر کل بانک اطلاعاتی مبتنی بر دیسک را در حافظه قرار دهید به کارآیی روش جداول بهینه سازی شدهی برای حافظه نخواهید رسید. زیرا در آن هنوز مفاهیمی مانند data pages و index pages به همراه یک buffer pool پیچیده وجود دارند. در روشهای مبتنی بر دیسک، ردیفها از طریق page id و row offset آنها قابل دسترسی میشوند. اما در جداول بهینه سازی شدهی برای حافظه، ردیفهای جداول با یک B-tree خاص به نام Bw-Tree در دسترس هستند.
میزان حافظهی مورد نیاز برای جداول بهینه سازی شدهی برای حافظه
باید درنظر داشت که تمام جداول بهینه سازی شدهی برای حافظه، به صورت کامل در حافظه ذخیره خواهند شد. بنابراین بدیهی است که نیاز به مقدار کافی حافظه در اینجا ضروری است. توصیه صورت گرفته، داشتن حافظهای به میزان دو برابر اندازهی اطلاعات است. البته در اینجا چون با یک سیستم هیبرید سر و کار داریم، حافظهی کافی جهت کار buffer pool مختص به جداول مبتنی بر دیسک را نیز باید درنظر داشت.
همچنین اگر به اندازهی کافی حافظه در سیستم تعبیه نشود، شاهد شکست مداوم تراکنشها خواهید بود. به علاوه امکان بازیابی و restore جداول را نیز از دست خواهید داد.
البته لازم به ذکر است که اگر کل بانک اطلاعاتی شما چند ترابایت است، نیازی نیست به همین اندازه یا بیشتر حافظه تهیه کنید. فقط باید به اندازهی جداولی که قرار است جهت قرار گرفتن در حافظه بهینه سازی شوند، حافظه تهیه کنید که حداکثر آن 256 گیگابایت است.
چه برنامههایی بهتر است از امکانات OLTP درون حافظهای SQL Server 2014 استفاده کنند؟
- برنامههایی که در آنها تعداد زیادی تراکنش کوتاه مدت وجود دارد به همراه درجهی بالایی از تراکنشهای همزمان توسط تعداد زیادی کاربر.
- اطلاعاتی که توسط برنامه زیاد مورد استفاده قرار میگیرند را نیز میتوان در جداول بهینه سازی شده جهت حافظه قرار داد.
- زمانیکه نیاز به اعمال دارای write بسیار سریع و با تعداد زیاد است. چون در جداول بهینه سازی شدهی برای حافظه، صفحات دادهها و ایندکسها وجود ندارند، نسبت به حالت مبتنی بر دیسک، بسیار سریعتر هستند. در روشهای متداول، برای نوشتن اطلاعات در یک صفحه، مباحث همزمانی و قفلگذاری آنرا باید در نظر داشت. در صورتیکه در روش بهینه سازی شدهی برای حافظه، به صورت پیش فرض از حالتی همانند snapshot isolation و همزمانی مبتنی بر نگارشهای مختلف رکورد استفاده میشود.
- تنظیم و بهینه سازی جداولی با تعداد Read بالا. برای مثال، جداول پایه سیستم که اطلاعات تعاریف محصولات در آن قرار دارند. این نوع جداول عموما با تعداد Readهای بالا و تعداد Write کم شناخته میشوند. چون طراحی جداول مبتنی بر حافظه از hash tables و اشارهگرهایی برای دسترسی به رکوردهای موجود استفاده میکند، اعمال Read آن نیز بسیار سریعتر از حالت معمول هستند.
- مناسب جهت کارهای data warehouse و ETL Staging Table. در جداول مبتنی بر حافظه امکان عدم ذخیره سازی اطلاعات بر روی دیسک سخت نیز پیش بینی شدهاست. در این حالت فقط اطلاعات ساختار جدول، ذخیرهی نهایی میگردد و اگر سرور نیز ری استارت گردد، مجددا میتواند اطلاعات خود را از منابع اصلی data warehouse تامین کند.
محدودیتهای جداول بهینه سازی شدهی برای حافظه در SQL Server 2014
- تغیر اسکیما و ساختار جداول بهینه سازی شدهی برای حافظه مجاز نیست. به بیان دیگر دستور ALTER TABLE برای اینگونه جداول کاربردی ندارد. این مورد جهت ایندکسها نیز صادق است. همان زمانیکه جدول ایجاد میشود، باید ایندکس آن نیز تعریف گردد و پس از آن این امکان وجود ندارد.
تنها راه تغییر اسکیمای اینگونه جداول، Drop و سپس ایجاد مجدد آنها است.
البته باید درنظر داشت که SQL Server 2014، اولین نگارش این فناوری را ارائه دادهاست و در نگارشهای بعدی آن، بسیاری از این محدودیتها قرار است که برطرف شوند.
- جداول بهینه سازی شدهی برای حافظه حتما باید دارای یک ایندکس باشند. البته اگر یک primary key را برای آنها تعریف نمائید، کفایت میکند.
- از unique indexها پشتیبانی نمیکند، مگر اینکه از نوع primary key باشد.
- حداکثر 8 ایندکس را میتوان بر روی اینگونه جداول تعریف کرد.
- امکان تعریف ستون identity در آن وجود ندارد. اما میتوان از قابلیت sequence برای رسیدن به آن استفاده کرد.
- DML triggers را پشتیبانی نمیکند.
- کلیدهای خارجی و قیود را پشتیبانی نمیکند.
- حداکثر اندازهی یک ردیف آن 8060 بایت است. بنابراین از نوعهای دادهای max دار و XML پشتیبانی نمیکند.
این مورد در حین ایجاد جدول بررسی شده و اگر اندازهی ردیف محاسبهی شدهی آن توسط SQL Server 2014 بیش از 8060 بایت باشد، جدول را ایجاد نخواهد کرد.
اگر سرور را ری استارت کنیم، چه اتفاقی برای اطلاعات جداول بهینه سازی شدهی برای حافظه رخ میدهد؟
حالت DURABILTY انتخاب شدهی در حین ایجاد جدول بهینه سازی شدهی برای حافظه، تعیین کنندهای این مساله است. اگر SCHEMA_ONLY انتخاب شده باشد، کل اطلاعات شما با ری استارت سرور از دست خواهد رفت؛ البته اطلاعات ساختار جدول حفظ خواهد گردید. اگر حالت SCHEMA_AND_DATA انتخاب شود، اطلاعات شما پس از ریاستارت سرور نیز در دسترس خواهد بود. این اطلاعات به صورت خودکار از لاگ تراکنشها بازیابی شده و مجددا در حافظه قرار میگیرند.
حالت SCHEMA_ONLY برای مصارف برنامههای data warehouse بیشتر کاربرد دارد. جایی که اطلاعات قرار است از منابع دادهی مختلفی تامین شوند.
برای مطالعه بیشتر
SQL Server 2014: NoSQL Speeds with Relational Capabilities
SQL Server 2014 In-Memory OLTP Architecture and Data Storage
Overview of Applications, Indexes and Limitations for SQL Server 2014 In-Memory OLTP Tables
Microsoft SQL Server 2014: In-Memory OLTP Overview
SQL Server in Memory OLTP for Database Developers
Exploring In-memory OLTP Engine (Hekaton) in SQL Server 2014 CTP1
- جزئیات نحوه پیاده سازی یک Storage Provider برای ASP.NET Identity
- تشریح اینترفیس هایی که باید پیاده سازی شوند، و نحوه استفاده از آنها در ASP.NET Identity
- ایجاد یک دیتابیس MySQL روی Windows Azure
- نحوه استفاده از یک ابزار کلاینت (MySQL Workbench) برای مدیریت دیتابیس مذکور
- نحوه جایگزینی پیاده سازی سفارشی با نسخه پیش فرض در یک اپلیکیشن ASP.NET MVC
پیاده سازی یک Storage Provider سفارشی برای ASP.NET Identity
- <UserStore<TUser
- IdentityUser
- <RoleStore<TRole
- IdentityRole
Roles
در مخزن پیش فرض ASP.NET Identity EntityFramework کلاسهای بیشتری برای موجودیتها مشاهده میکنید.
- IdentityUserClaim
- IdentityUserLogin
- IdentityUserRole
public Task<IList<Claim>> GetClaimsAsync(IdentityUser user) { ClaimsIdentity identity = userClaimsTable.FindByUserId(user.Id); return Task.FromResult<IList<Claim>>(identity.Claims.ToList()); }
public class IdentityUser : IUser { public IdentityUser(){...} public IdentityUser(string userName) (){...} public string Id { get; set; } public string UserName { get; set; } public string PasswordHash { get; set; } public string SecurityStamp { get; set; } }
public class UserStore : IUserStore<IdentityUser>, IUserClaimStore<IdentityUser>, IUserLoginStore<IdentityUser>, IUserRoleStore<IdentityUser>, IUserPasswordStore<IdentityUser> { public UserStore(){...} public Task CreateAsync(IdentityUser user){...} public Task<IdentityUser> FindByIdAsync(string userId){...} ... }
public class IdentityRole : IRole { public IdentityRole(){...} public IdentityRole(string roleName) (){...} public string Id { get; set; } public string Name { get; set; } }
public class RoleStore : IRoleStore<IdentityRole> { public RoleStore(){...} public Task CreateAsync(IdentityRole role){...} public Task<IdentityRole> FindByIdAsync(string roleId){...} .... }
- MySQLDatabase: این کلاس اتصال دیتابیس MySql و کوئریها را کپسوله میکند. کلاسهای UserStore و RoleStore توسط نمونه ای از این کلاس وهله سازی میشوند.
- RoleTable: این کلاس جدول Roles و عملیات CRUD مربوط به آن را کپسوله میکند.
- UserClaimsTable: این کلاس جدول UserClaims و عملیات CRUD مربوط به آن را کپسوله میکند.
- UserLoginsTable: این کلاس جدول UserLogins و عملیات CRUD مربوط به آن را کپسوله میکند.
- UserRolesTable: این کلاس جدول UserRoles و عملیات CRUD مربوطه به آن را کپسوله میکند.
- UserTable: این کلاس جدول Users و عملیات CRUD مربوط به آن را کپسوله میکند.
ایجاد یک دیتابیس MySQL روی Windows Azure
در ویزارد Choose Add-on به سمت پایین اسکرول کنید و گزینه ClearDB MySQL Database را انتخاب کنید. سپس به مرحله بعد بروید.
4. راهکار Free بصورت پیش فرض انتخاب شده، همین گزینه را انتخاب کنید و نام دیتابیس را به IdentityMySQLDatabase تغییر دهید. نزدیکترین ناحیه (region) به خود را انتخاب کنید و به مرحله بعد بروید.
5. روی علامت checkmark کلیک کنید تا دیتابیس شما ایجاد شود. پس از آنکه دیتابیس شما ساخته شد میتوانید از قسمت ADD-ONS آن را مدیریت کنید.
6. همانطور که در تصویر بالا میبینید، میتوانید اطلاعات اتصال دیتابیس (connection info) را از پایین صفحه دریافت کنید.
7. اطلاعات اتصال را با کلیک کردن روی دکمه مجاور کپی کنید تا بعدا در اپلیکیشن MVC خود از آن استفاده کنیم.
ایجاد جداول ASP.NET Identity در یک دیتابیس MySQL
CREATE TABLE `IdentityMySQLDatabase`.`users` ( `Id` VARCHAR(45) NOT NULL, `UserName` VARCHAR(45) NULL, `PasswordHash` VARCHAR(100) NULL, `SecurityStamp` VARCHAR(45) NULL, PRIMARY KEY (`id`)); CREATE TABLE `IdentityMySQLDatabase`.`roles` ( `Id` VARCHAR(45) NOT NULL, `Name` VARCHAR(45) NULL, PRIMARY KEY (`Id`)); CREATE TABLE `IdentityMySQLDatabase`.`userclaims` ( `Id` INT NOT NULL AUTO_INCREMENT, `UserId` VARCHAR(45) NULL, `ClaimType` VARCHAR(100) NULL, `ClaimValue` VARCHAR(100) NULL, PRIMARY KEY (`Id`), FOREIGN KEY (`UserId`) REFERENCES `IdentityMySQLDatabase`.`users` (`Id`) on delete cascade); CREATE TABLE `IdentityMySQLDatabase`.`userlogins` ( `UserId` VARCHAR(45) NOT NULL, `ProviderKey` VARCHAR(100) NULL, `LoginProvider` VARCHAR(100) NULL, FOREIGN KEY (`UserId`) REFERENCES `IdentityMySQLDatabase`.`users` (`Id`) on delete cascade); CREATE TABLE `IdentityMySQLDatabase`.`userroles` ( `UserId` VARCHAR(45) NOT NULL, `RoleId` VARCHAR(45) NOT NULL, PRIMARY KEY (`UserId`, `RoleId`), FOREIGN KEY (`UserId`) REFERENCES `IdentityMySQLDatabase`.`users` (`Id`) on delete cascade on update cascade, FOREIGN KEY (`RoleId`) REFERENCES `IdentityMySQLDatabase`.`roles` (`Id`) on delete cascade on update cascade);
ایجاد یک اپلیکیشن ASP.NET MVC و پیکربندی آن برای استفاده از MySQL Provider
6. در پنجره New ASP.NET Project قالب MVC را انتخاب کنید و تنظیمات پیش فرض را بپذیرید.
7. در پنجره Solution Explorer روی پروژه IdentityMySQLDemo کلیک راست کرده و Manage NuGet Packages را انتخاب کنید. در قسمت جستجوی دیالوگ باز شده عبارت "Identity.EntityFramework" را وارد کنید. در لیست نتایج این پکیج را انتخاب کرده و آن را حذف (Uninstall) کنید. پیغامی مبنی بر حذف وابستگیها باید دریافت کنید که مربوط به پکیج EntityFramework است، گزینه Yes را انتخاب کنید. از آنجا که کاری با پیاده سازی فرض نخواهیم داشت، این پکیجها را حذف میکنیم.
8. روی پروژه IdentityMySQLDemo کلیک راست کرده و Add, Reference, Solution, Projects را انتخاب کنید. در دیالوگ باز شده پروژه AspNet.Identity.MySQL را انتخاب کرده و OK کنید.
9. در پروژه IdentityMySQLDemo پوشه Models را پیدا کرده و کلاس IdentityModels.cs را حذف کنید.
10. در پروژه IdentityMySQLDemo تمام ارجاعات ";using Microsoft.AspNet.Identity.EntityFramework" را با ";using AspNet.Identity.MySQL" جایگزین کنید.
11. در پروژه IdentityMySQLDemo تمام ارجاعات به کلاس "ApplicationUser" را با "IdentityUser" جایگزین کنید.
12. کنترلر Account را باز کنید و متد سازنده آنرا مطابق لیست زیر تغییر دهید.
public AccountController() : this(new UserManager<IdentityUser>(new UserStore(new MySQLDatabase()))) { }
13. فایل web.config را باز کنید و رشته اتصال DefaultConnection را مطابق لیست زیر تغییر دهید.
<add name="DefaultConnection" connectionString="Database=IdentityMySQLDatabase;Data Source=<DataSource>;User Id=<UserID>;Password=<Password>" providerName="MySql.Data.MySqlClient" />
مقادیر <DataSource>, <UserId> و <Password> را با اطلاعات دیتابیس خود جایگزین کنید.
اجرای اپلیکیشن و اتصال به دیتابیس MySQL
5. در این مرحله کاربر جدید باید ایجاد شده و وارد سایت شود.
6. به ابزار MySQL Workbench بروید و محتوای جداول IdentityMySQLDatabase را بررسی کنید. جدول users را باز کنید و اطلاعات کاربر جدید را بررسی نمایید.
برای ساده نگاه داشتن این مقاله از بررسی تمام کدهای لازم خودداری شده، اما اگر مراحل را دنبال کنید و سورس کد نمونه را دریافت و بررسی کنید خواهید دید که پیاده سازی تامین کنندگان سفارشی برای ASP.NET Identity کار نسبتا ساده ای است.
آینده SQL Server CE
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
پس از آن سرویس بدون مشکل استارت شد.