جواد جهانگیری
جواد جهانگیری
خواندن ۳۸ دقیقه·۳ سال پیش

امن سازی Web Api در (C# asp.net core) با استفاده از Identity و JWT


به نام آن که جان را فکرت آموخت / چراغ دل به نور جان برافروخت

با سلام و تشکر از مطالعه مقالات بنده در کانال ویرگول در این مقاله به بحث در مورد web api و نحوه امن سازی web api ها و مسایل مربوط به Authentication و Authorization پرداخته می شود در مورد JWT صحبت می شود و از Identity مایکروسافت برای احراز هویت استفاده خواهد شد سعی می شود در یک آموزش کاربردی و پروژه محور نحوه ثبت نام کاربر ، لاگین کاربر ،ایجاد و دریافت توکن و احراز هویت از طریق توکن بررسی شده است.ایده این سری مقاله های آموزشی از این موضوع سرچشمه می گیرد که بخشی از خوانندگان وجود دارد که به محتوای نوشتاری آنلاین بهتر پاسخ می دهند و ترجیج می دهند مهارت های جدید را به سرعت از طریق خواندن افزایش دهند.این سری اموزش ها با ارایه پکیج آموزش های کاربردی در خصوص C# asp.net core آغاز می شود که انتظار می رود با واکنش مثبت کاربران همراه شود.

توجه: این مقاله به مرور زمان، ویرایش و یا تکمیل می‌شود!
تقاضا: در صورتی که با مشکل تایپی، دستوری و یا مفهومی در این مقاله برخورد کردید، از شما دوست عزیز و گرامی، صمیمانه تقاضا می‌کنم که اینجانب را مطلع کرده، تا نسبت به تصحیح و یا تکمیل آن، در اسرع وقت، اقدام نمایم.
با کمال تشکر
جواد جهانگیری
شماره تلفن همراه: 09149431772
نشانی پست الکترونیکی: javad.jahangiri.niopdc@gmail.com
فیلم‌های آموزشی در آپارات:جواد جهانگیری (CTO) - آپارات
فیلم آموزشی در یوتویب: javad jahangiri - YouTube
نسخه مقاله: ۱.۱ - تاریخ بروزرسانی: 1400/09/09

کاراموزان و دانشجویان عزیز منبع اصلی تهیه این مقاله قسمت امنیت شرکت مایکروسافت به شرح ذیل می باشد

https://docs.microsoft.com/en-us/aspnet/core/security/?view=aspnetcore-6.0


همانگونه که مستحضرید این روزها بازار اپلیکیشن های RESTful داغ هستش و دیگر برنامه ها فقط بصورت وب نمی باشد برای مثال برنامه های اندرویدی و یا برنامه های گوشی های ایفون در نظر بگیرد که با سرورهای که بصورت RESTful سرویس می دهند کار می کند و یا میکروسرویس ها در نظر بگیرد که برای ارتباطات خود از تکنولوژی RESTful استفاده می کنند برای ارتباط با این تکنولوژی از یک قالب خاص داده ای استفاده می شو اول با فرمت XML اطلاعات ارسال و دریافت می شود و د رحال حاظر نیز از فرمت JSON استفاده می شود در حقیقت JSON یک قالب دیتای می باشد که فارغ از اینکه در سمت کلاینت و یا سرور از چه زبان برنامه نویسی استفاده می شود برای نقل و اطلاعات داده ها استفاده می شود

JSON

مخفف عبارت JavaScript Object Notation (نشانه گذاری شی جاوا اسکریبت) می باشد در حقیقت یک قالب سبک وزن برای دخیره و حمل و نقل دیتا می باشد .

مثال زیر یک شئ با نام “employees” به معنای کارمندان تعریف کرده است که مقدار این شی حاوی آرایه‌ای با ۳ عنصر است. که هر عنصر آرایه یک شئ است که مشخصات یک کارمند را دربر می‌گیرد.


{ &quotemployees&quot:[ {&quotfirstName&quot:&quotJohn&quot, &quotlastName&quot:&quotDoe&quot}, {&quotfirstName&quot:&quotAnna&quot, &quotlastName&quot:&quotSmith&quot}, {&quotfirstName&quot:&quotPeter&quot, &quotlastName&quot:&quotJones&quot} ] }

قواعد نحوه نوشتن JSON

  • داده‌ها در جفت‌هایی بصورت نام/مقدار (name/value) قرار می‌گیرد.
  • داده‌ها با علامت کاما از هم جدا می‌شوند.
  • علامت‌های { } اشیاء را نگه می‌دارند.
  • علامت‌های [ ] آرایه‌ها را نگه می‌دارند.


JWT

برای درک توکن JWT ابتدا وارد سایت زیر می شویم :

https://jwt.io/

دقت کنید JWT مخفف JSON Web Token می باشد

در توکن قسمت قرمز رنگ در حقیقت همان Header بوده و قسمت بنفش هم قسمت Payload بوده و قسمت آبی رنگ هم قسمت Signature هستش

دو روش کلی و پرکاربرد اعتبارسنجی سمت سرور، برای برنامه‌های سمت کاربر وب وجود دارند:

  • روش اول Cookie-Based Authentication که پرکاربردترین روش بوده و در این حالت به ازای هر درخواست، یک کوکی جهت اعتبارسنجی کاربر به سمت سرور ارسال می‌شود (و برعکس).
  • روش دوم Token-Based Authentication که بر مبنای ارسال یک توکن امضا شده به سرور، به ازای هر درخواست است.

مزیت‌های استفاده‌ی از روش مبتنی بر توکن چیست؟

  • دامنه‌های متفابل Cross-domain / CORS: کوکی‌ها و CORS آنچنان با هم سازگاری ندارند، چون صدور یک کوکی وابسته‌ است به دومین مرتبط به آن و استفاده‌ از آن در سایر دومین‌ها عموما پذیرفته شده نیست، اما روش مبتنی بر توکن، وابستگی به دومین صدور آن‌ را ندارد و اصالت آن بر اساس روش‌های رمزنگاری تصدیق می‌شود.
  • بدون حالت بودن و مقیاس پذیری سمت سرور: در حین کار با توکن‌ها، نیازی به ذخیره‌ اطلاعات داخل سشن سمت سرور نیست و توکن موجودیتی است خود شمول (self-contained). به این معنا که حاوی تمام اطلاعات مرتبط با کاربر بوده و محل ذخیره‌ی آن در local storage و یا کوکی سمت کاربر می‌باشد. (البته اگر نیاز به مدیریت توکن‌ها داشته باشید نباید این مورد درنظر بگیرید)
  • توزیع برنامه با CDN: حین استفاده از روش مبتنی بر توکن، امکان توزیع تمام فایل‌های برنامه (جاوا اسکریپت، تصاویر و غیره) توسط CDN وجود دارد و در این حالت کدهای سمت سرور، تنها یک API ساده خواهد بود.
  • عدم در هم تنیدگی کدهای سمت سرور و کلاینت: در حالت استفاده‌ از توکن، این توکن می‌تواند از هرجایی و هر برنامه‌ای صادر شود و در این حالت نیازی نیست تا وابستگی ویژه‌ای بین کدهای سمت کلاینت و سرور وجود داشته باشد.
  • سازگاری بهتر با سیستم‌های موبایل: در حین توسعه‌ برنامه‌های بومی پلتفرم‌های مختلف موبایل، کوکی‌ها روش مطلوبی جهت کار با APIهای سمت سرور نیستند. تطابق یافتن با روش‌های مبتنی بر توکن در این حالت ساده‌تر است.
  • باگ CSRF: از آنجایی که از کوکی استفاده نمی‌شود، نیازی به نگرانی در مورد حملات CSRF نیست. چون دیگر برای مثال امکان سو استفاده‌ از کوکی فعلی اعتبارسنجی شده، جهت صدور درخواست‌هایی با سطح دسترسی شخص لاگین شده وجود ندارد، چون این روش کوکی را به سمت سرور ارسال نمی‌کند.
  • کارآیی بهتر: حین استفاده‌ از توکن‌ها، به علت ماهیت خود شمول آنها، رفت و برگشت کمتری به بانک اطلاعاتی صورت گرفته و سرعت بالاتری را شاهد خواهیم بود. (البته اگر نیاز به مدیریت توکن‌ها داشته باشید نباید این مورد درنظر بگیرید)
  • امکان نوشتن آزمون‌های یکپارچگی ساده‌تر: در حالت استفاده‌ از توکن‌ها آزمودن یکپارچگی برنامه نیازی به رد شدن از صفحه‌ی لاگین را ندارد و پیاده سازی این نوع آزمون‌ها ساده‌تر از قبل است.
  • استاندارد بودن: امروزه همینقدر که استاندارد JSON Web Token را پیاده سازی کرده باشید، امکان کار با انواع و اقسام پلتفرم‌ها و کتابخانه‌ها را خواهید یافت.

اما JWT یا JSON Web Token چیست؟

توضیح: JSON Web Token یا JWT یک استاندارد وب است (RFC 7519) که روشی فشرده و خود شمول (self-contained) را جهت انتقال امن اطلاعات بین مقاصد مختلف را توسط یک شی JSON تعریف می‌کند. این اطلاعات قابل تصدیق و اطمینان هستند، از این‌ رو که به صورت دیجیتال امضا می‌شوند. JWTها توسط یک کلید خصوصی (با استفاده از الگوریتم HMAC) و یا یک جفت کلید خصوصی و عمومی (توسط الگوریتم RSA) قابل امضا شدن هستند.
در این تعریف واژه‌هایی مانند «فشرده» و «خود شمول» بکار رفته‌اند:
- «فشرده بودن»: اندازه‌ی شی JSON یک توکن در این حالت کوچک بوده و به سادگی از طریق یک URL و یا پارامترهای POST و یا داخل یک HTTP Header قابل ارسال است و به دلیل کوچک بودن این اندازه انتقال آن نیز سریع است.
- «خود شمول»: بار مفید (payload) این توکن شامل تمام اطلاعات مورد نیاز جهت اعتبارسنجی یک کاربر است تا دیگر نیازی به کوئری گرفتن هر باره‌ از بانک اطلاعاتی نباشد (در این روش مرسوم است که فقط یکبار از بانک اطلاعاتی کوئری گرفته شده و اطلاعات مرتبط با کاربر را امضای دیجیتال کرده و به سمت کاربر ارسال می‌کنند).

جوت‌ها دارای سه قسمت است و این قسمت‌ها با نقطه از هم جا شدند، مانند: xxxxx.yyyyy.zzzzz که شامل سه بخش: header.payload.signature می‌باشند و هر بخش با الگوریتم Base64 اینکد می‌شود. نمونه‌ای از یک توکن جوت:

1eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o

بخش Header:

بخش Header عموما دارای دو قسمت است که نوع توکن و الگوریتم مورد استفاده‌ توسط آن را مشخص می‌کند. نوع توکن در اینجا JWT است و الگوریتم‌های مورد استفاده، عموما HMAC SHA256 و یا RSA هستند. نمونه اطلاعات دیکد شده بخش هدر:

1234{ &quotalg&quot: &quotRS256&quot, &quottyp&quot: &quotJWT&quot }

بخش payload:

بخش payload یا «بار مفید» توکن، شامل claims است، منظور از claims اطلاعاتی است در مورد موجودیت مدنظر (عموما کاربر) و یک سری متادیتای اضافی. سه نوع claim وجود دارند:

نوع اول Reserved claims: یک سری اطلاعات مفید و از پیش تعیین شده‌ غیراجباری هستند مانند:iss یا صادر کنند، exp یا تاریخ انقضا، sub یا عنوان (subject) و aud یا مخاطب (audience)

نوع دوم Public claims: می‌تواند شامل اطلاعاتی باشد که توسط IANA JSON Web Token Registry پیشتر ثبت شده‌است و فضاهای نام آنها تداخلی نداشته باشند.

نوع سوم Private claims: ادعای سفارشی هستند که جهت انتقال داده‌ها بین مقاصد مختلف مورد استفاده قرار می‌گیرند.

نمونه اینکد شده بخش payload توکن:

123456{ &quotexp&quot: 1520507268, &quotsub&quot: 582946, &quotname&quot: &quotErFUN KH&quot, &quotadmin&quot: true }

در نمونه بالا دو دیتای اول از نوع Reserved claims می‌باشد و دو دیتای آخر از نوع Private claims.

به طور استاندارد بخش Reserved claims می‌تونه شامل این موارد باشه:

  • فیلد iss یا issuer: صادر کننده توکن در این قسمت مشخص میشه، برای مثال مقدارش می‌تونه "hesabfun.com" باشه.
  • فیلد sub یا subject: در اینجا موضوع اصلی توکن مطرح میشه، مثلا موضوع توکن ما شناسایی کاربرانه، پس یوزر آیدی کاربر توش قرار میدیم تا متوجه بشیم کسی که توکن برامون ارسال کرده کیه.
  • فیلد aud یا audience: در این قسمت مشخص می‌کنیم این توکن باید کجا مورد استفاده قرار بگیره، این مواقعی کاربرد داره که شما چندتا سرور داشته باشید و همه از یک کلید خصوصی برای امضا استفاده می‌کنند. برای مثال مقدارش می‌تونه "https://blog.hesabfun.com" باشه.
  • فیلد exp یا expiration: در این قسمت مشخص میکنیم توکن تا چه زمانی اعتبار داره، این تاریخ بصورت Unix time مشخص می‌کنیم.
  • فیلد nbf یا not before: در این قسمت مشخص می‌کنیم توکن از چه تاریخی به بعد باید مورد مورد پردازش قرار بگیره، یعنی ممکنه توکن زودتر ایجاد کنیم ولی فعلا اجازه استفاده از اون نداشته باشند.
  • فیلد iat یا issuedAt: تاریخ ایجاد توکن به صورت Unix time اینجا قرار میدیم، بیشتر برای اینکه متوجه بشیم توکن جدیده یا نه استفاده میشه.
  • فیلد jti یا jwt id: آیدی منحصر به فرد برای هر توکن، اگه سیستم مدیریت توکن تلگرام دیده باشید متوجه میشید میتونه همچین استفاده‌ای داشته باشه، بهتره برای بلاک کردن، کل توکن تو دیتابیس قرار ندید و به هرکدوم یه آیدی بدید اینجوری دیتابیس سبک‌تری دارید.

این مقادیر همینجا تموم نمیشه، میتونید نگاهی به لیست مایکروسافت کنید، ولی بهتره خیلی شلوغش نکنید، مهم همین‌ها هستند که خیلی وقت‌ها استفاده نمیشن نهایتا sub و exp استفاده می‌کنند.

بخش signature:

تا اینا دیدیم همه دیتاهای با الگوریتم بیس۶۴ اینکد شد که به راحتی تو هرسیستمی دیکد میشه (اگه با این شیوه آشنا نیستید باید بگم فقط کاراکترهای غیر مجاز به حروف تبدیل میکنه، مقاله ویکی‌پدیا بخونید) و هرکسی می‌تونه همچین توکنی بسازه و برای ما ارسال کنه ولی نه با وجود بخش سوم (امضا).

همونطوری که می‌بینید بخش اول (هدر) با بخش دوم (پیلود) جمع شده و بعد با کلید خصوصی (کلید خصوصی فقط در سرور موجوده) رمز میشه، این به عنوان بخش سوم یا امضا توکن ما استفاده میشه، درصورتی که اطاعات پیلود دست کاری بشه امضا برای سرور معتبر نیست، همچنین چون کاربران کلید خصوصی ندارند نمی‌تونند خودشون توکن تولید کنند.

همینطور درنظر داسته باشید اطلاعات حساس مثل پسورد یا... داخل توکن نذارید چون هرکسی می‌تونه به سادگی توکن باز کنه و دیتای داخلش بخونه، ولی اگر واقعا نیازه اطلاعات حساس داخلش بذارید باید از JWE استفاده کنید.

نکته:
توجه شود با عنایت به اینکه اطلاعات در توکن Jwtرمز نشده و فقط بصورت base64 اینکد می شود لذا ما در سامانه های که نیاز به امنیت بیشتری دارند از پروتکل https برای زمز نگاری اطلاعات استفاده می کنیم

چرخه حیات jwt

1.ابتدا کاربر به نام کاربری و رمز صحیح در سامانه ما login می کند

2.در صورت موفق بودن login به سامانه برنامه یک توکن jwt ایجاد می کند و این توکن را به سمت کلاینت ارسال می کند در توکن در امضا اطلاعات header و payload با یک کلید رمز می شود توجه شود اطلاعات header و Payload خودشان رمز نشده و بصورت base64 فقط encode می شود و براحتی می شود این اطلاعات را decode کرد.

3.کلاینت این توکن را ذخیره کرده و بخاطر ماهیت Stateless بودن پروتکل http بهمراه هر درخواست در Header درخواست توکن jwt را نیز ارسال می کند

4.سرور توکن ارسال بهمراه درخواست دریافت کرده قسمت امضا را با کلیدی که در روی سرور می باشد از رمز خارج می کند و با اطلاعات Headerو payload تطبیق می دهد در صورت درست بودن امضا سرور به درخواست Response می دهد و در غیر اینصورت خطای عدم احراز هویت می دهد



ویدیوی پیشنهادی

در این سری از اموزش های خودم به اموزش کاربردی ایجاد web api در asp.net core با jwt بهمراه swagger پرداخته می شود.

https://www.aparat.com/v/qAjUN



ASP.NET Core authentication

Authentication ( احراز هویت) :   وظیفه اینو داره که هویت کاربر رو بررسی کنه. آیا کاربر وجود داره یا نه؟ آیا مشخصات وارد شده کاربر صحیح هست یا نه؟ اصلا کاربری با این مشخصات وحود داره؟ (کلا کارش یقه کاربر رو گرفتنه.)

Authentication فرآیند تعیین هویت کاربر است.

Authorization (مجوز) :   خب حالا که فهمیدیم کاربر وجود داره و مشخصاتی که وارد کرده صحیح بوده، حالا باید بررسی کنیم کاربر عزیزمون چه دسترسی هایی(Permission) داره.(همون Role هایی که براش انتخاب میکنیم و میره توی قسمت های مختلف سایت حال میکنه واسه خودش)

Authorization ?فرآیند تعیین اینکه آیا کاربر به یک منبع دسترسی دارد یا خیر.

در ASP.NET Core، احراز هویت توسط سرویس IAuthenticationService انجام می شود که این سرویس توسط Middleware احراز هویت استفاده می شود.سرویس احراز هویت (authentication service) از کنترل کننده های احراز هویت ثبت شده (registered authentication handlers) برای تکمیل اقدامات مربوط به احراز هویت استفاده می کند.

نمونه هایی از اقدامات مرتبط با احراز هویت ( registered authentication handlers ) به شرح ذیل می باشد:

  • احراز هویت یک کاربر
  • هنگامی که یک کاربر احراز هویت نشده سعی می کند به یک منبع محدود دسترسی پیدا کند، وارد عمل می شود.

کنترل کننده های احراز هویت ثبت شده (registered authentication handlers ) و گزینه های پیکربندی آنها "schemes" نامیده می شوند.

برای ثبت Authentication schemes می بایستی وارد Startup و قسمت ConfigureService می شویم و به شرح ذیل عمل می کنیم:

  • روش اول که بیشتر استفاده می شود با فراخوانی extention متد خاص اسکیمای مورد نظر بعد از فراخوانی services.AddAuthentication برای مثال AddJwtBearer یا AddCookie را می توان نام برد . این اکستنشن متدها از AuthenticationBuilder.AddScheme برای ثبت اسکمیا به شرح ذیل استفاده می کنند
  • روش دوم که کمتر استفاده می شود با فراخوانی مستقیم AuthenticationBuilder.AddScheme می باشد.

برای مثال ) این کد نحوه ثبت authentication services and handlers برای ookie and JWT bearer authentication schemes به شرح ذیل را نمایش می دهد


services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => Configuration.Bind(&quotJwtSettings&quot, options)) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => Configuration.Bind(&quotCookieSettings&quot, options));

پارمتر JwtBearerDefaults.AuthenticationScheme در AddAuthentication نام اسکیمای می باشد که در مواقعی که اسکیمای مشخص درخواست نشده است استفاده می شود

اگر اسکیماهای مختلفی استفاده شود authorization policies (or authorization attributes) می تواند اسکیمای احراز هویت (و یا اسکیماهای) که کاربر برای احزار هویت به ان وابسته است را مشخص کند

درمثال بالا، cookie authentication scheme را می توان با مشخص کردن نام آن ((CookieAuthenticationDefaults.AuthenticationScheme بطور پیش فرض) ،گرچه هنگام فراخوانی AddCookie می توان نام دیگری ارائه داد).

در برخی موارد، با فراخوانی AddAuthentication به طور خودکار با روش های دیگر extension methods انجام می شود. به عنوان مثال، هنگام استفاده از ASP.NET Core Identity اکتنشن متد AddAuthentication به صورت داخلی فراخوانی می شود.

برای استفاده از Authentication middleware می بایستی extension method (اکستنشن متد) UseAuthentication بر روی app's IApplicationBuilder فراخوانی شود.فراخوانی UseAuthentication میان افزاری را که ازregistered authentication schemes ثبت شده قبلی استفاده می کند را ثبت می کند.قبل از هر میان افزاری که به احراز هویت کاربران بستگی دارد، UseAuthentication را فراخوانی کنید. هنگام استفاده از مسیریابی endpoint routing، فراخوانی UseAuthentication باید انجام شود.

  • پس از UseRouting، به طوری که اطلاعات مسیر برای تصمیم گیری های احراز هویت در دسترس باشد.
  • قبل از UseEndpoints، به طوری که کاربران قبل از دسترسی به نقاط پایانی احراز هویت شوند.

حتما برای درک بهتر مطالب مقاله زیر مطالعه شود:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/?view=aspnetcore-6.0

تکنولوژِی Swagger یا OpenAPI

تکنولوژِی Swagger یا OpenAPI یک استاندارد مستقل از زبان است که برای توصیف API های REST است. در واقع Swagger هم به کامپیوتر و هم به انسان این امکان را می دهد که قابلیت های REST API را بدون دسترسی مستقیم به source code درک کنند. اهداف اصلی آن عبارتند از:

  • میزان کار مورد نیاز برای اتصال سرویس های جدا شده را به حداقل برسانید.
  • زمان مورد نیاز برای مستندسازی دقیق سرویس ها را کاهش دهید.

بررسی OpenApi با Swagger

پروژه Swagger در سال 2015 به ابتکار OpenAPI اهدا شد و از آن زمان به عنوان OpenAPI نامیده می شود. هر دو نام به جای یکدیگر استفاده می شوند. با این حال “OpenAPI” به مشخصات اشاره دارد و “Swagger” به گروه های open-source و تجاری از SmartBear اشاره می کند که با مشخصات OpenAPI کار می کنند. محصولات متن باز یا open-source بعدی مانند OpenAPIGenerator نیز با وجود عدم انتشار توسط SmartBear تحت نام خانوادگی Swagger قرار می گیرند.

به طور خلاصه می توان گفت:

  • OpenAPI یک استاندارد است.
  • Swagger ابزاری است که از مشخصات OpenAPI استفاده می کند. به عنوان مثال: OpenAPIGenerator و SwaggerUI.

استاندارد OpenAPI (openapi.json)

استاندارد OpenAPI سندی است که قابلیت های API شما را توصیف می کند. این سند بر اساس XML و attribute annotation ها در کنترلرها و مدل ها است. این بخش اصلی جریان OpenAPI است و برای هدایت ابزارهایی مانند SwaggerUI استفاده می شود. به طور پیش فرض، نام آن openapi.json است

رابط کاربری Swagger

رابط کاربری Swagger یک UI مبتنی بر وب ارائه می دهد که اطلاعات مربوط به سرویس را با استفاده از مشخصات OpenAPI ایجاد شده ارائه می دهد. درواقع Swashbuckle و NSwag شامل یک نسخه تعبیه شده از رابط کاربری Swagger هستند، به طوری که می توان آن را با استفاده از یک middleware در برنامه ASP.NET Core شما میزبانی کرد.

مستندسازی API اغلب یک کار خسته کننده و در عین حال ضروری تلقی می شود. با استفاده از OpenAPI یا Swagger که به خوبی با ASP.NET Core ادغام شده است، می توانید این کار را بر اینکار را انجام دهید

Microsoft.AspNetCore.Authentication.JwtBearer

ASP.NET Core middleware that enables an application to receive an OpenID Connect bearer token


Bearer Authentication

احراز هویت حامل (Bearer authentication)که احراز هویت توکن (token authentication) نیز نامیده می شود) یک طرح احراز هویت HTTP است که شامل توکن های امنیتی (security tokens)به نام توکن های حامل (bearer tokens)است. نام "احراز هویت حامل" (Bearer authentication) را می توان به عنوان "give access to the bearer of this token" درک کرد. توکن حامل (bearer token) یک رشته رمزی است که معمولاً توسط سرور در پاسخ به درخواست ورود ایجاد می شود. هنگام درخواست برای منابع محافظت شده، مشتری باید این نشانه را در هدر Authorization ارسال کند

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.jwtbearer?view=aspnetcore-6.0


AddJwtBearer Method

تنظیمات متد AddJwtBearer یک چنین مفاهیمی را به همراه دارند:
- تنظیم SaveToken به true، به این معنا است که می‌توان به توکن دریافتی از سمت کاربر، توسط متد HttpContext.GetTokenAsync در کنترلرهای برنامه دسترسی یافت.
در قسمت تنظیمات TokenValidationParameters آن:
- کار خواندن فایل appsettings.json برنامه جهت تنظیم صادر کننده و مخاطبین توکن انجام می‌شود. سپس IssuerSigningKey به یک کلید رمزنگاری متقارن تنظیم خواهد شد. این کلید نیز در تنظیمات برنامه قید می‌شود.
- تنظیم ValidateIssuerSigningKey به true سبب خواهد شد تا میان‌افزار اعتبارسنجی، بررسی کند که آیا توکن دریافتی از سمت کاربر توسط برنامه‌ی ما امضاء شده‌است یا خیر؟
- تنظیم ValidateLifetime به معنای بررسی خودکار طول عمر توکن دریافتی از سمت کاربر است. اگر توکن منقضی شده باشد، اعتبارسنجی به صورت خودکار خاتمه خواهد یافت.
- ClockSkew به معنای تنظیم یک تلرانس و حد تحمل مدت زمان منقضی شدن توکن در حالت ValidateLifetime است. در اینجا به صفر تنظیم شده‌است.

سپس به قسمت JwtBearerEvents می‌رسیم:
- OnAuthenticationFailed زمانی فراخوانی می‌شود که اعتبارسنج‌های تنظیمی فوق، با شکست مواجه شوند. برای مثال طول عمر توکن منقضی شده باشد و یا توسط ما امضاء نشده‌باشد. در اینجا می‌توان به این خطاها دسترسی یافت و درصورت نیاز آن‌ها را لاگ کرد.
- OnChallenge نیز یک سری دیگر از خطاهای اعتبارسنجی را پیش از ارسال آن‌ها به فراخوان در اختیار ما قرار می‌دهد.
- Received برای حالتی است که توکن دریافتی، توسط هدر مخصوص Bearer به سمت سرور ارسال نمی‌شود. عموما هدر ارسالی به سمت سرور یک چنین شکلی را دارد

OnTokenValidated پس از کامل شدن اعتبارسنجی توکن دریافتی از سمت کاربر فراخوانی می‌شود


claim چیست و چه ارتباطی به سطح دسترسی امنیتی دارد؟

امروزه بنای امنیت براساس Claim  در نرم افزارهای مبتنی بر وب دارای رویکرد بسیار خوبی است .اما همه درک نمی کنند  که claim چیست و چرا باید در نرم افزارهای کاربردی مورد استفاده قرار گیرد. البته مهم تراز معماری و نیازسنجی برای طراحی یک اپلیکیشن، مکانیزم امنیت براساس دسترسی نقش مورد نظر یا براساس امنیت claim یا حتی بدون هیچ  احراز هویت و بدون مکانیزم دسترسی است .

با این اوصاف claim یک ویژگی است که برای توصیف کردن یک موضوع استفاده میشود(از دید ما ،شناسایی هویت).

شناسایی تشخیص هویت یک روش متداول است که در برنامه های کاربردی برای بدست آوردن اطلاعات لازم در مورد هویت کاربران داخل سازمان خودمان ، سازمان های دیگر و در اینترنت مورد استفاده قرار میگیرد.

این اصطلاح همانند تفاوت در اختیارات در زمینه دسترسی ها روابط گسترده ای دارد. به عنوان مثال ، سن کاربران در تماشای یک فیلم ترسناک یک نوع سطح دسترسی است. بر اساس claim ، این یک مجوز تشخیص هویت است ، به عنوان مثال : همه افراد دارای سن بالاتر از 16 می توانند (بعضی کار ها را )انجام دهند. اما این امر برای شناسایی هویت ها در مورد ویژگی هایی همانند "سن"  وقتی " همه افرادی که میتوانند فیلم ترسناک نگاه کنند باید ..... ساله  باشند" آسان نیست.

بنابراین claim یک ویژگی از هویت است که مجوز ها را تعریف میکند ، زمانیکه مجوزهای درستی  برای انجام دادن کاری هستند.

Identity on ASP.NET Core


Asp.net Identity يك راه جديد براي احراز هويت در پروژه هاي دات نت توسط مايكروسافت مي باشد. آن يك مكانيسم رايج براي به كارگيري در تمام فريم ورك هاي مايكروسافت از جمله web form، mvc، web api و غيره مي باشد. آن متدها و ويژگي هايي را براي مديريت كارربان و نقش ها در دات نت در اختيار ما قرار مي دهد.

Identity در ASP.NET Core ، یک سیستم عضویت است که قابلیت ورود به سیستم را به برنامه ‏های ASP.NET Core اضافه می‏کند.

کاربران می توانند با اطلاعات ورود به سیستم ذخیره شده در Identity یک حساب ایجاد کنند یا می توانند از یک ارائه دهنده ی( login provider) ورود خارجی استفاده کنند.

فراهم کننده های ورود به سیستم خارجی شامل Facebook، Google، Microsoft Account، و Twitter هستند.

Identity می تواند با استفاده از پایگاه داده ی SQL Server جهت ذخیره ی نام های کاربری، رمز عبورها، و داده های پروفایل پیکربندی شود.

همچنین، انباره ی پایدار دیگری می تواند مورد استفاده قرار بگیرد، برای مثال، Azure Table Storage.

همانطور که داستان سیستم عضویت ASP.NET طی سالیان تغییر و رشد کرده است، تیم ASP.NET نیز آموخته‌های زیادی از بازخورد‌های مشتریان شان بدست آورده اند.

این پیش فرض که کاربران شما توسط یک نام کاربری و کلمه عبور که در اپلیکیشن خودتان هم ثبت شده است به سایت وارد خواهند شد، دیگر معتبر نیست. دنیای وب اجتماعی شده است. کاربران از طریق وب سایت‌ها و شبکه‌های اجتماعی متعددی با یکدیگر در تماس هستند، خیلی از اوقت بصورت زنده! شبکه هایی مانند Facebook و Twitter.

با در نظر گرفتن تغییراتی که در توسعه اپلیکیشن‌های وب بوجود آمده ASP.NET Identity با اهداف زیر متولد شد:

  • یک سیستم هویت واحد (One ASP.NET Identity system)
    • سیستم ASP.NET Identity می‌تواند در تمام فریم ورک‌های مشتق از ASP.NET استفاده شود. مانند ASP.NET MVC, Web Forms, Web Pages, Web API و SignalR
    • از این سیستم می‌توانید در تولید اپلیکیشن‌های وب، موبایل، استور (Store) و یا اپلیکیشن‌های ترکیبی استفاده کنید.
  • سادگی تزریق داده‌های پروفایل درباره کاربران
    • روی الگوی دیتابیس برای اطلاعات کاربران و پروفایل‌ها کنترل کامل دارید. مثلا می‌توانید به سادگی یک فیلد، برای تاریخ تولد در نظر بگیرید که کاربران هنگام ثبت نام در سایت باید آن را وارد کنند.
  • کنترل ذخیره سازی/واکشی اطلاعات
    • بصورت پیش فرض ASP.NET Identity تمام اطلاعات کاربران را در یک دیتابیس ذخیره می‌کند. تمام مکانیزم‌های دسترسی به داده‌ها توسط EF Code First کار می‌کنند.
    • از آنجا که روی الگوی دیتابیس، کنترل کامل دارید، تغییر نام جداول و یا نوع داده فیلد‌های کلیدی و غیره ساده است.
    • استفاده از مکانیزم‌های دیگر برای مدیریت داده‌های آن ساده است، مانند SharePoint, Windows Azure Storage Table و دیتابیس‌های NoSQL.
  • تست پذیری
    • ASP.NET Identity تست پذیری اپلیکیشن وب شما را بیشتر می‌کند. می‌توانید برای تمام قسمت هایی که از ASP.NET Identity استفاده می‌کنند تست بنویسید.
  • تامین کننده نقش (Role Provider)
    • تامین کننده ای وجود دارد که به شما امکان محدود کردن سطوح دسترسی بر اساس نقوش را می‌دهد. بسادگی می‌توانید نقش‌های جدید مانند "Admin" بسازید و بخش‌های مختلف اپلیکیشن خود را محدود کنید.
  • Claims Based
    • ASP.NET Identity از امکان احراز هویت بر اساس Claims نیز پشتیبانی می‌کند. در این مدل، هویت کاربر بر اساس دسته ای از اختیارات او شناسایی می‌شود. با استفاده از این روش توسعه دهندگان برای تعریف هویت کاربران، آزادی عمل بیشتری نسبت به مدل Roles دارند. مدل نقش‌ها تنها یک مقدار منطقی (bool) است؛ یا عضو یک نقش هستید یا خیر، در حالیکه با استفاده از روش Claims می‌توانید اطلاعات بسیار ریز و دقیقی از هویت کاربر در دست داشته باشید.
  • تامین کنندگان اجتماعی
    • به راحتی می‌توانید از تامین کنندگان دیگری مانند Microsoft, Facebook, Twitter, Google و غیره استفاده کنید و اطلاعات مربوط به کاربران را در اپلیکیشن خود ذخیره کنید.
  • Windows Azure Active Directory
    • برای اطلاعات بیشتر به این لینک مراجعه کنید.
  • یکپارچگی با OWIN
    • ASP.NET Identity بر اساس OWIN توسعه پیدا کرده است، بنابراین از هر میزبانی که از OWIN پشتیبانی می‌کند می‌توانید استفاده کنید. همچنین هیچ وابستگی ای به System.Web وجود ندارد. ASP.NET Identity یک فریم ورک کامل و مستقل برای OWIN است و می‌تواند در هر اپلیکیشنی که روی OWIN میزبانی شده استفاده شود.
    • ASP.NET Identity از OWIN برای ورود/خروج کاربران در سایت استفاده می‌کند. این بدین معنا است که بجای استفاده از Forms Authentication برای تولید یک کوکی، از OWIN CookieAuthentication استفاده می‌شود.
  • پکیج NuGet
    • ASP.NET Identity در قالب یک بسته NuGet توزیع می‌شود. این بسته در قالب پروژه‌های ASP.NET MVC, Web Forms و Web API که با Visual Studio 2013 منتشر شدند گنجانده شده است.
    • توزیع این فریم ورک در قالب یک بسته NuGet این امکان را به تیم ASP.NET می‌دهد تا امکانات جدیدی توسعه دهند، باگ‌ها را برطرف کنند و نتیجه را بصورت چابک به توسعه دهندگان عرضه کنند.

انواع هویت سنجی در ASP Core Identity

بزار Identity در ASP Core مسئولیت تشخیص هویت و کنترلر دسترسی را به عهده دارد. این ابزار در نسخه های قبل هم وجود داشت اما مانند سایر قسمتها باز نویسی شده است. در اینجا به سه روش اصلی کنترل دسترسی در Idenity Core می پردازیم.

روش Role-Based

در این روش کاربر بر اساس سمتی که دارد به بخش هایی از سایت دسترسی پیدا می کند. مثلا دسترسی به بخش مدیریت سایت فقط برای کاربرهایی با سمت Admin میسر است. در اینجا ما یک جدول برای نگه داری سمت ها داریم و یک جدول هم برای نگه داری رابطه ی بین کاربران با هر سمت. یک کاربر می تواند چندین سمت داشته باشد.

روش Claims-Based

نسخه ی جدید ASP Core تاکید زیادی به استفاده از این روش دارد. در این روش یک کاربر می تواند چند هویت داشته باشد. هر هویت مشخصه های خودش را دارد. دسترسی های یک کاربر بر اساس مشخصه های هر هویت فرق می کند. مثلا شما برای گرفتن وام به بانک مراجعه می کنید و برای شناسایی کارت ملی ارائه می کنید. مشخصات کارت ملی بخشی از مشخصات شما شامل نام و تاریخ تولد را نشان می دهد و یکی از هویت های شما محسوب میشود. حالا اگر بخواهید وام دانشجویی بگیرید باید ثابت کنید دانشجو هستید. در این مرحله کارت دانشجویی ارائه می کنید که شامل نام دانشگاه و شماره ی دانشجویی است. در سیستم Claims-Based انواع مشخصات شما در یک جدول key/value دخیره می شود و بعدا می توانید دسترسی به اکشن ها و کنترلر ها را بر اساس آن محدود کنید.

روش Policy-Based

این شیوه ترکیبی از روشهای قبل است. می توانید برای اجرای هر کدام از اکشنها یک سیاست یا Policy تعریف کنید که می تواند شامل مجموعه از سمت ها و مشخصه های هویتی (Claims) باشد.

علاوه بر اینها چند روش دیگر هم وجود دارد و باید گفت نسخه ی جدید از هر نظر کامل است. به طور کلی پیاده کردن سیستم امنیتی پیچیده است و بهتر است همیشه از Identity استفاده کنید. این سیستم بسیاری از نکات مهم مانند رمز نگاری را به خوبی رعایت کرده است و سطح امنیت سایت را به میزان قابل توجهی بالا می برد.



جدول نقش‌های سیستم

کار با ارث بری از نگارش جنریک کلاس IdentityRole شروع می‌شود. این کلاس پایه، حاوی تعاریف اصلی فیلدهای جدول نقش‌های سیستم است که اولین آرگومان جنریک آن، نوع کلید اصلی جدول مرتبط را نیز مشخص می‌کند و در اینجا به int تنظیم شده‌است. همچنین یک اینترفیس جدید IAuditableEntity را نیز در انتهای این تعریف‌ها مشاهده می‌کنید. در مورد این اینترفیس و Shadow properties متناظر با آن، در ادامه‌ی بحث با سفارشی سازی DbContext برنامه بیشتر توضیح داده خواهد شد.در اولین بار اجرای برنامه، نقش Admin در این جدول ثبت خواهد شد.

جدول کاربران منتسب به نقش‌ها

کلاس پایه‌ی جدول کاربران منتسب به نقش‌ها، کلاس جنریک IdentityUserRole است که در اینجا با تغییر آرگومان جنریک آن به int، نوع فیلدهای UserId و RoleId آن به int تنظیم می‌شوند. در کلاس سفارشی سازی شده‌ی فوق، دو خاصیت اضافه‌تر User و Role نیز را مشاهده می‌کنید. مزیت تعریف آن‌ها، دسترسی ساده‌تر به اطلاعات کاربران و نقش‌ها توسط EF Core است.در اولین بار اجرای برنامه، کاربر شماره 1 یا همان Admin به نقش شماره 1 یا همان Admin، انتساب داده می‌شود.


جدول جدید IdentityRoleClaim سیستم

در ASP.NET Core Identity، جدول جدیدی به نام RoleClaim نیز اضافه شده‌است. در این سری از آن برای پیاده سازی سطوح دسترسی پویای به صفحات استفاده خواهیم کرد. ابتدا یک سری نقش ثابت در جدول Roles ثبت خواهند شد. سپس تعدادی کاربر به هر نقش نسبت داده می‌شوند. اکنون می‌توان به هر نقش نیز تعدادی Claim را انتساب داد. برای مثال یک Claim سفارشی که شامل ID سفارشی area:controller:action باشد. به این ترتیب و با بررسی سفارشی آن می‌توان سطوح دسترسی پویا را نیز پیاده سازی کرد و مزیت آن این است که تمام این Claims به صورت خودکار به کوکی شخص نیز اضافه شده و دسترسی به اطلاعات آن بسیار سریع است و نیازی به مراجعه‌ی به بانک اطلاعاتی را ندارد.

جدول UserClaim سیستم

می‌توان به هر کاربر یک سری Claim مخصوص را نیز انتساب داد. برای مثال مسیر عکس ذخیره شده‌ی او در سرور، چه موردی است و این اطلاعات به صورت خودکار به کوکی او نیز توسط ASP.NET Core Identity اضافه می‌شوند. البته ما در این سری روش دیگری را برای سفارشی سازی Claims عمومی کاربران بکار خواهیم گرفت (با سفارشی سازی کلاس ApplicationClaimsPrincipalFactory آن).


جداول توکن و لاگین‌های کاربران

دراینجا نیز نحوه‌ی سفارشی سازی و تغییر جداول لاگین‌های کاربران و توکن‌های مرتبط با آن‌ها را مشاهده می‌کنید. این جداول بیشتر جهت دسترسی به حالت‌هایی مانند لاگین با حساب کاربری جی‌میل مورد استفاده قرار می‌گیرند و کاربرد پیش فرضی ندارند (اگر از تامین کننده‌های لاگین خارجی نمی‌خواهید استفاده کنید).


جدول کاربران سیستم

در اینجا علاوه بر نحوه‌ی تغییر نوع کلید اصلی جدول کاربران سیستم، نحوه‌ی افزودن خواص اضافه‌تری مانند نام، تاریخ تولد، مکان، تصویر و غیره را نیز مشاهده می‌کنید. به علاوه جدولی نیز جهت ثبت سابقه‌ی کلمات عبور هش شده‌ی کاربران نیز تدارک دیده شده‌است تا کاربران نتوانند از 5 کلمه‌ی عبور اخیر خود (تنظیم NotAllowedPreviouslyUsedPasswords در فایل appsettings.json) استفاده کنند.فیلد IsActive نیز از این جهت اضافه شده‌است تا بجای حذف فیزیکی یک کاربر، بتوان اکانت او را غیرفعال کرد.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-6.0&tabs=visual-studio



یک پروژه از نوع ASP.NET CORE WEB API ایجاد می کنیم

یک اسم برای پروژه انتخاب می کنیم

آخرین نسخه NET رو انتخاب می کنیم

در ابتدای پروژه نسبت به نصب پکیج های به شرح ذیل اقدام می کنیم:

Install-Package Microsoft.EntityFrameworkCore -Version 5.0.12

Install-Package Microsoft.EntityFrameworkCore.Design -Version 5.0.12

Installing NuGet package Microsoft.EntityFrameworkCore.tools 5.0.12

Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 5.0.12

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore -version 5.0.12

Install-Package Microsoft.AspNetCore.Identity.UI -Version 5.0.12

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -version 5.0.12



وارد فایل Startup شده و در قسمت ConfigureServices کدهای زیر را اضافه می کنیم

using System.Text; var key = Encoding.ASCII.GetBytes(&quot@#MY_BIG_SECRET_KEY@#&quot);

سپس کد زیر را بعد از کد مذکور به شرح ذیل اضافه می کنیم


using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; ; }).AddJwtBearer(options => { options.Events = new JwtBearerEvents { OnTokenValidated = context => { //TODO CODE return Task.CompletedTask; } }; options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; });

سپس یک احزار هویت به پروژه اضافه می کنیم

app.UseAuthentication();


یک کنترلر به پروژه به اسم SecurityController از نوع web api empty به پروژه اضافه می کنیم:

using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; namespace SecurityWebApi.Controllers { [Route(&quotapi/[controller]&quot)] [ApiController] [Authorize] public class SecurityController : ControllerBase { [HttpGet(&quotgetFruits&quot)] [AllowAnonymous] public ActionResult GetFruits() { List<string> mylist = new List<string>() { &quotapples&quot, &quotbannanas&quot }; return Ok(mylist); } [HttpGet(&quotgetFruitsAuthenticated&quot)] public ActionResult GetFruitsAuthenticated() { List<string> mylist = new List<string>() { &quotorganic apples&quot, &quotorganic bannanas&quot }; return Ok(mylist); } } }

پروژه رو اجرا می کنیم :

چون روی کنترلر [Authorize] اعمال شده است لذا چون احرازهویت نشده است پیغام Error: Unauthorized می دهید


یک پوشه Models به پروژه اضافه می کنیم و یک کلاس فایل MyLoginModelType به پروژه اضافه می کنیم:


namespace SecurityWebApi.Models { public class MyLoginModelType { public string Email { get; set; } public string Password { get; set; } } }



در این قسمت متد مربوط به ساختن توکن را ایجاد می کنیم توجه شود چون تا اینجای پروژ هنوز Identity به پروژه اضافه نشده است قسمت بررسی ایمیل و رمز عبور بصورت هارد کد پیاده سازی شده است.

[AllowAnonymous] [HttpPost(&quotgetToken&quot)] public async Task<ActionResult> GetToken([FromBody] MyLoginModelType myLoginModelType) { if(myLoginModelType.Email==&quotjavad.jahangiri.niopdc@gamil.com&quot &&myLoginModelType.Password==&quotPa$$w0rd&quot) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(&quot@#MY_BIG_SECRET_KEY@#&quot); var tokenDescription = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, myLoginModelType.Email) } ), Expires = DateTime.UtcNow.AddDays(1), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),SecurityAlgorithms.HmacSha256Signature), }; var token = tokenHandler.CreateToken(tokenDescription); var tokenString = tokenHandler.WriteToken(token); return Ok(new { token = tokenString }); } else { return Ok(&quotfailed , try again&quot); } }

در اینجا کاربر با ارسال ایمیل و رمز عبوردر صورت صحیح بودن اطلاعات برای ان توکن ساخته و ارسال می شود

در این قسمت نحوه ارسال توکن در هدر درخواست از طریق نرم افزار postman نمایش داده شده:

در این مرحله اضافه کردن کنترلر Identitiy به پروژه به شرح ذیل می باشد

در ادامه یک DataContext برای ارتباط Identity با دیتابیس sqlserver ایجادمیشود

در این قسمت کلاس سفارشی کاربر برای Identity ایجاد می شود

حال Identity به شرح ذیل به پروژه اضافه می شود:

بعد از اضافه شدن کنترلر Identity جمله اتصال را عوض می کنیم

بعد نسبت به ایجاد مایگریشن و بروزرسانی دیتابیس عمل می کنیم:

Add-Migration createIdentitySchema
Update-Database

همانگونه که مشاهده می کنید دیتابیس به شرح زیر ساخته می شود:

به فایل Startup بر می گردیم :

کدهای زیر را به ان اضافه می کنیم

var userMachine = context.HttpContext.RequestServices.GetRequiredService<UserManager<SecurityWebApiUser>>(); var user = userMachine.GetUserAsync(context.HttpContext.User); if (user == null) context.Fail(&quotUnAuthorized&quot);

مسیر دسترسی به فایل SecurityWebApiUser مسیر SecurityWebApi.Areas.Identity.Data می باشد

حالا به کنترلر Securtiy بر می گردیم و ایتم های زیر را به پروژه اینجکت می کنیم

private readonly SecurityWebApiContext _dbContext; private readonly UserManager<SecurityWebApiUser> _userManager; private readonly SignInManager<SecurityWebApiUser> _signInManager; public SecurityController(SecurityWebApiContext dbContext, UserManager<SecurityWebApiUser> userManager, SignInManager<SecurityWebApiUser> signInManager) { _dbContext = dbContext; _userManager = userManager; _signInManager = signInManager; }

و در نهایت تابع دریافت توکن و ثبت نام را به شرح ذیل در پروژه تغییر می دهیم که بتوانیم با کمک Identityیک کاربر را در دیتابیس ایجاد کنیم از طریق ان لاگین نموده و توکن را دریافت کنیم

[AllowAnonymous] [HttpPost(&quotgetToken&quot)] public async Task<ActionResult> GetToken([FromBody] MyLoginModelType myLoginModelType) { var user = _dbContext.Users.FirstOrDefault(x => x.Email == myLoginModelType.Email); if (user != null) { var singInResult = await _signInManager.CheckPasswordSignInAsync(user, myLoginModelType.Password, false); if (singInResult.Succeeded) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(&quot@#MY_BIG_SECRET_KEY@#&quot); var tokenDescription = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, myLoginModelType.Email) } ), Expires = DateTime.UtcNow.AddDays(1), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature), }; var token = tokenHandler.CreateToken(tokenDescription); var tokenString = tokenHandler.WriteToken(token); return Ok(new { token = tokenString }); } else { return Ok(&quotfailed , try again&quot); } } return Ok(&quotfailed , try again&quot); } [AllowAnonymous] [HttpPost(&quotregister&quot)] public async Task<IActionResult> Register([FromBody] MyLoginModelType myLoginModelType) { SecurityWebApiUser securingWebApiDotNetCoreWithIdentity = new SecurityWebApiUser() { Email = myLoginModelType.Email, UserName = myLoginModelType.Email, EmailConfirmed = false, }; var result = await _userManager.CreateAsync(securingWebApiDotNetCoreWithIdentity, myLoginModelType.Password); if (result.Succeeded) { return Ok(new { result = &quotRegister Success&quot }); } else { StringBuilder sb = new StringBuilder(); foreach (var error in result.Errors) { sb.Append(error.Description); } return Ok(new { Result = $&quotRegister Fail: {sb.ToString()}&quot }); } }



در تصویر زیر مشاهده می کنیم که یک کاربر در دیتابیس ایجاد می شود

نکته :دقت شود بصورت پیش فرض در Identity در قسمت SignIn گزینه RequireConfirmedAccount فعال می باشد باید انرا غیرفعال کنیم


در نهایت حالا می تواند همانند توضیحات قبلی با این کاربر درخواست یک توکن داده و از طریق این توکن webapi مورد نظر خود را احراز هویت نمایید.


برای دانلود سورس پروژه از گیت هاب بنده استفاده کنید

https://github.com/javadjahangiriniopdc/SecuringWebApiDotNetCoreWithIdentityAndJwt



https://www.aparat.com/javadjahangiriniopdc




با تشکر از مطالعه این مقاله ,مثل همیشه کنجکاو باشید!!!

در دوره های آموزش تضمینی مجتمع فنی ارومیه که به صورت خصوصی و عمومی در دو شیوه حضوری و آنلاین برگزار می شود سرفصل های بسیار متنوع و کاربردی را بصورت پروژه محور آموزش داده می شود تا شخص کارآموز بتواند بلافاصله پس از اتمام این دوره در کمترین زمان ممکن وارد بازار کار شود.
آموزش تخصص ماست با ما حرفه ای شوید
جهت مشاوره با شماره 09149431772 در ارتباط باشید ...
امن سازی Web Api در 5 .NET با استفاده از Identity و JWTجواد جهانگیریمجتمع فنی ارومیهآموزش سی شارپ در ارومیهآموزش برنامه نویسی در ارومیه
بنده دارای مدارک بین المللی شبکه ,برنامه نویسی, سرورهای ویندوزی و لینوکس هستم بیش از ده سال سابقه تدریس در زمینه های یاد شده را دارم. آموزش تخصص ماست با ما حرفه ای شوید 09149431772 مجتمع فنی ارومیه
شاید از این پست‌ها خوشتان بیاید