بررسی فرمت کوکیهای ASP.NET Identity
آقای نصیری در آخرین سوال گفتید که باید از UpdateSecurityStampAsync استفاده بشه. من تو برنامم ، بر اساس هر Application_AuthenticateRequest میام چک میکنم که اگر کاربر حذف یا قفل یا ... بود به صورت خودکار Signout بشه. با توجه به نکته امنیتی که که شما گفتید باید اینجا هم از UpdateSecurityStampAsync استفاده بشه ، من به این صورت استفاده کردم :
public class MvcApplication : HttpApplication { public MvcApplication() { var wrapper = new EventHandlerTaskAsyncHelper(AuthenticateRequest); AddOnAuthenticateRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler); } private async Task AuthenticateRequest(object sender, EventArgs e) { if (Context.User == null) return; //bla bla if (هرچیزی که مجاز نباشد) { var authenticationManager = ProjectObjectFactory.Container.GetInstance<IAuthenticationManager>(); authenticationManager.SignOut ( DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.ApplicationCookie ); FormsAuthentication.SignOut(); await userService.UpdateSecurityStampAsync(userId); } } }
در عمل چک کردم جواب داد ، البته مجبور بودم از یک EventHandlerTaskAsyncHelper استفاده کنم چون نمیشد تو خود متد Application_AuthenticateRequest متدهای Async تعریف کرد.
سوال من اینه ، آیا اصلا نیاز هست در اینجا هم security stamp رو آپدیت کنیم ؟ یا اصلا این روشی که من رفتم از نظر امنیتی درست هست یا خیر.
با تشکر
Claim Based Identity
Relying Party (RP) = Application
Service Providers (SP) = Application
RP یا SP یک Application میباشد که از Claim استفاده میکند. واژهی Relying Party بدین دلیل انتخاب شده که Application روی یک Issuer به منظور تامین اطلاعات در مورد یک Identity تکیه میکند.
Subject = User
Principal = User
واژهی Subject یا Principal در حقیقت یک User میباشد. این واژه زمانی معنا پیدا میکند که شما به User به عنوان یک Subject برای کنترل دسترسی، شخصی سازی (Personalization) و ... بنگرید. در Net Framework. به جای Subject از Principal استفاده میشود.
Security Token Service (STC) = Issuer
از دید فنی، STC یک رابط درون یک Issuer میباشد که درخواستها (Request) را تأیید و اقدام به ساخت Issues Security Token (توکنهای مسائل امنیتی) مینماید. توکنهای مسائل امنیتی شامل یک سری Claim میباشند.
Identity Provider (IDP) = Issuer
تامین کننده Identity یک Issuer یا Token Issuer میباشد که وظیفهی تعیین اعتبار (Validation) کاربر مانند نام کاربری، رمز عبور و ... را بر عهده دارد.
Active Client = Smart or rich Client
Passive Client = Browser
یک Active Client میتواند از یک کتابخانهی پیچیده مانند WCF به منظور پیاده سازی پروتکلهایی که بتوانند یک Security Token را درخواست و پاس دهند، استفاده نمایند. به منظور پشتیبانی از مرورگرهای مختلف، سناریوهای passive از پروتکلهای سادهتری به منظور درخواست و پاس دادن یک Security Token که بر روی پروتکل Http تکیه دارد استفاده میکند (Http Post - Http Get).
و اما Claim چیست؟
در حقیقت Claim عبارتست از یک بیانیه یا شرح که یک Subject در مورد خودش یا Subject دیگری میسازد. این بیانیه میتواند در مورد یک نام، هویت، کلید، گروه، حق دسترسی و یا یک قابلیت باشد. Claimها بوسیله یک Provider صادر و سپس بسته بندی (Package) شده و بوسیلهی یک Issuer صادر میشوند که این Issuer عموما با نام Security Token Service شناخته میشود.
به منظور آشنایی با این مبحث میتوانید به اینجا و اینجا مراجعه نمایید.
این نوشتار مقدمهای بود بر مباحث ASP.NET Identity. بنده در حال ترجمهی سه فصل آخر کتاب Pro ASP.NET Mvc 5 Platform که اختصاص به مبحث Identity دارد هستم. فصل 13 تقریبا تمام شده و انشالله بزودی آنرا منتشر میکنم.
لغو Lazy Loading در حین کار با AutoMapper و Entity Framework
در نگارش 5 این کتابخانه، قسمت «تهیه نگاشتهای AutoMapper» بجای استفاده از متد Configure، از خود سازندهی کلاس جهت معرفی نگاشتها استفاده میکند. بنابراین امضای متدهای Configure را حذف و با سازندهی کلاس جایگزین کنید.
تدارک یک آزمایش برای بررسی میزان افزایش کارآیی Reflection در دات نت 7
یک برنامهی کنسول جدید را ایجاد کرده و سپس کلاس Person را به صورت زیر به آن اضافه میکنیم:
namespace NET7Reflection; public class Person { private int _age; internal Person(int age) => _age = age; private int GetAge() => _age; private void SetAge(int age) => _age = age; }
به همین جهت ابتدا کتابخانهی BenchmarkDotNet را با TargetFramework دات نت 7 به صورت زیر به پروژه اضافه میکنیم:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="BenchmarkDotNet" Version="0.13.4" /> </ItemGroup> </Project>
using System.Reflection; using BenchmarkDotNet.Attributes; namespace NET7Reflection; [MemoryDiagnoser(false)] public class Benchmarks { private readonly object?[] _ageParams = { 30 }; private readonly ConstructorInfo _ctor = typeof(Person).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, new[] { typeof(int) })!; private readonly MethodInfo _getAgeMethod = typeof(Person).GetMethod("GetAge", BindingFlags.NonPublic | BindingFlags.Instance)!; private readonly Person _person = new(10); private readonly MethodInfo _setAgeMethod = typeof(Person).GetMethod("SetAge", BindingFlags.NonPublic | BindingFlags.Instance)!; [Benchmark] public int GetAge() => (int)typeof(Person).GetMethod("GetAge", BindingFlags.NonPublic | BindingFlags.Instance)! .Invoke(_person, Array.Empty<object?>())!; [Benchmark] public int GetAgeCachedMethod() => (int)_getAgeMethod.Invoke(_person, Array.Empty<object?>())!; [Benchmark] public void SetAge() => typeof(Person).GetMethod("SetAge", BindingFlags.NonPublic | BindingFlags.Instance)! .Invoke(_person, new object?[] { 30 }); [Benchmark] public void SetAgeCachedMethod() => _setAgeMethod.Invoke(_person, new object?[] { 30 }); [Benchmark] public void SetAgeCachedMethodCachedParams() => _setAgeMethod.Invoke(_person, _ageParams); [Benchmark] public Person Ctor() => (Person)typeof(Person).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, new[] { typeof(int) })! .Invoke(_person, new object?[] { 30 })!; [Benchmark] public Person CtorCachedCtorInfo() => (Person)_ctor.Invoke(_person, new object?[] { 30 })!; [Benchmark] public Person CtorCachedCtorInfoCachedParams() => (Person)_ctor.Invoke(_person, _ageParams)!; }
- در اینجا نحوهی کار با متدهای خصوصی کلاس Person را توسط Reflection مشاهده میکنید. برای مثال در متد GetAge، به نحو متداولی این کار صورت گرفتهاست. در متد GetAgeCachedMethod، قسمت دریافت اطلاعات متد، کش شدهاست و برای نمونه در متد SetAgeCachedMethodCachedParams، هم کش شدن قسمت دریافت اطلاعات متد را مشاهده میکنید و هم کش شدن پارامتر ارسالی به آنرا.
- این آزمایش را با فراخوانی زیر و تنظیم target framework به دات نت 6 و سپس دات نت 7، به صورت جداگانهای اجرا میکنیم:
using BenchmarkDotNet.Running; using NET7Reflection; BenchmarkRunner.Run<Benchmarks>();
و با target framework دات نت 7 به صورت زیر:
همانطور که مشاهده میکنید، در اکثر موارد، کارآیی Reflection در دات نت 7، حداقل 2 برابر نمونهی مشابه دات نت 6 است.
چه تغییری در دات نت 7 سبب بهبود قابل ملاحظهی کارآیی Reflection شدهاست؟
جزئیات تغییرات صورت گرفتهی در Reflection دات نت 7 را میتوانید در این pull request مشاهده کنید که در حقیقت از امکانات سطح پایین IL Emit استفاده کردهاند. در این مورد پیشتر تعدادی مطلب ذیل عنوان «آشنایی با Reflection.Emit» در این سایت منتشر شدهاند که میتوانید آنها را بررسی کنید.
در کل هرچند تغییرات جدید دات نت مانند ارائهی انواع و اقسام source generators، در تعدادی از موارد نیاز به Reflection را کمتر کردهاند و کارآیی بیشتری را ارائه دادهاند، اما Reflection هیچگاه منسوخ نخواهد شد و هرگونه بهبود کارآیی در این زمینه، بر روی کل فریمورک و برنامههای مشتق شدهی از آن، تاثیر قابل توجهی را خواهد گذاشت.
مسیر راه Bootstrap
Starting today, Bootstrap 3 will move to end of life, and will no longer receive critical security updates.
Bootstrap 4 moved to Long Term Support release on February 14, 2019 and will no longer receive new features. It will continue to receive bug fixes, security updates, and documentation updates.
Bootstrap 5 is under active development. You can follow our progress on GitHub.
آشنایی با مدل برنامه نویسی TAP
آشنایی با مدل برنامه نویسی TAP
- یک نمونه پروژه دات نت 4 که از DownloadStringTaskAsync استفاده میکند:
Async03DotNet4.zip
اگر نسخه دات نت کمتر از 4 باشه استفاده از قابلیت میسر نیست.