نظرات مطالب
اعتبارسنجی مبتنی بر JWT در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
آیا امکان انتقال تنظیمات jwt به لایه دیگر وجود دارد؟
منظورم از تنظیمات:
            services.AddAuthorization(options =>
                    {
                        options.AddPolicy(CustomRoles.Admin, policy => policy.RequireRole(CustomRoles.Admin));
                        options.AddPolicy(CustomRoles.User, policy => policy.RequireRole(CustomRoles.User));
                        options.AddPolicy(CustomRoles.Editor, policy => policy.RequireRole(CustomRoles.Editor));
                    });

            // Needed for jwt auth.
            services
                .AddAuthentication(options =>
                {
                    options.DefaultChallengeScheme = siteSettings.JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultSignInScheme = siteSettings.JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultAuthenticateScheme = siteSettings.JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(cfg =>
                {
                    cfg.RequireHttpsMetadata = false;
                    cfg.SaveToken = true;
                    cfg.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidIssuer = Configuration["BearerTokens:Issuer"], // site that makes the token
                        ValidateIssuer = false, // TODO: change this to avoid forwarding attacks
                        ValidAudience = Configuration["BearerTokens:Audience"], // site that consumes the token
                        ValidateAudience = false, // TODO: change this to avoid forwarding attacks
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["BearerTokens:Key"])),
                        ValidateIssuerSigningKey = true, // verify signature to avoid tampering
                        ValidateLifetime = true, // validate the expiration
                        ClockSkew = TimeSpan.Zero // tolerance for the expiration date
                    };
من نتونستم این سرویس هارو در لایه Ioc خودم ایجاد کنم. مشکلم هم بابت عدم وجود AddAuthentication   بود. هر چند من پکیج‌های زیر را اضافه کردم اما نتوانستم تمام سرویس‌ها رو تکمیل کنم
Microsoft.AspNetCore.Authorization  و Microsoft.AspNetCore.Authorization.Policy من از نسخه 3.1.201 استفاده میکنم
اشتراک‌ها
دوره سه ساعته آموزش Blazor

00:00:00 Introduction
00:03:07 Blazor Project Structure
00:12:14 How Blazor Works
00:20:28 What is an Inventory Management System
00:23:47 Introduction to Clean Architecture
00:30:58 Null Reference Type in .NET 6
00:36:44 Write the View Inventories Use Case
00:45:16 Implement the View Inventories Use Case
00:59:27 Create a Plugin with Dependency Injection
01:08:45 Inject the Use Case in Razor Component
01:17:35 Dependency Injection in Blazor
01:28:08 Page Component - Create the Inventory List Page
01:34:34 SPA Components Best Practice
01:38:07 Databinding and EventCallback in Search Inventory Component
01:52:59 Component Parameters in Inventory List Component
02:03:52 Null Checks
02:06:07 Extract the Inventory List Item Component
02:09:45 Add Inventory Use Case
02:12:10 Implement Add Inventory Repository Methods
02:15:34 NavigationManager
02:17:56 EditForm and Data Validation
02:30:09 Edit Inventory Use Case
02:35:12 Implement Edit Inventory Repository methods
02:43:00 Receive Routing Parameters
02:50:09 Implement Edit Inventory Component
03:03:06 Why we are using Async everywhere 

دوره سه ساعته آموزش Blazor
نظرات مطالب
Blazor 5x - قسمت 31 - احراز هویت و اعتبارسنجی کاربران Blazor WASM - بخش 1 - انجام تنظیمات اولیه
- از بین می‌رود. باید آن‌را در local storage ذخیره کنید.
- بله. نمونه اینکار در پروژه‌ی «پیاده سازی سیاست‌های دسترسی پویای سمت سرور و کلاینت در برنامه‌های Blazor WASM» پس از لاگین انجام شده.
- خیر؛ نیازی نیست. توکن‌ها به همراه امضای دیجیتال هستند و همچنین کلید رمزنگاری خصوصی آن بر روی سرور ذخیره می‌شود. کسی که توانسته در سمت کلاینت توکنی را تغییر دهد و آن‌را از مرحله‌ی اعتبارسنجی خودکار سمت سرور رد کند (یعنی امضای دیجیتال تغییرات انجام شده را مجددا محاسبه و به توکن اعمال کرده)، به سرور شما و کلیدهای رمزنگاری خصوصی آن دسترسی دارد؛ یک چنین شخصی نیازی به دستکاری توکنی را ندارد، چون هم اکنون دسترسی او به سرور شما کامل است! محتوای یک JWT، هرچند قابل مشاهده و مطالعه است، اما امضاء شده‌است. یک چنین محتوای امضاء شده‌ای، در جاهای حساس دیگری هم کاربرد واقعی دارد: «تهیه XML امضاء شده جهت تولید مجوز استفاده از برنامه» 
نظرات مطالب
Blazor 5x - قسمت 31 - احراز هویت و اعتبارسنجی کاربران Blazor WASM - بخش 1 - انجام تنظیمات اولیه
- فلسفه‌ی کار با Blazor server، امکان دسترسی مستقیم به لایه سرویس‌های برنامه، بدون نیاز به طراحی یک Web API خاص آن‌ها است (کار با آن ساده‌تر است). اگر قرار است با Web API کار کنید، شاید بهتر باشد از WASM استفاده کنید.
- سرویس‌های Blazor Server، طول عمر خاصی دارند و تا زمانیکه اتصال برقرار است، از دست نمی‌روند. بنابراین خیلی از اطلاعات را می‌توان به صورت متداولی در آن‌ها ذخیره کرد و نیازی به تمهید خاصی نیست؛ هرچند encrypted local storage هم دارند.
- امکان طراحی interceptor برای HTTP Client هم وجود دارد تا هربار نیازی به مقدار دهی هدر Authorization نباشد.
- بله. در این سری اگر از Identity استفاده شده، بیشتر هدف مدیریت کاربران بوده و یا برای Blazor Server، دسترسی به کوکی خودکار پس از لاگین. نکات تهیه‌ی authentication provider سفارشی مطرح شده‌ی در قسمت wasm این سری برای کار با JWT، همه جا یکسان است و وابستگی به Identity و یا حتی Identity server پیش‌فرض مطرح شده‌ی توسط مایکروسافت، ندارد.
نظرات مطالب
اعتبارسنجی مبتنی بر JWT در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
- راه حل عمومی برای jQuery، React و Angular و غیره این است که جائیکه if (xhr.status === 401) را از سمت سرور دریافت کردید (401، خروجی خودکار فیلتر Authorize، در صورت شکست اعتبارسنجی است)، می‌توانید پیام خاصی و یا هدایت به صفحه‌ی خاصی را با فراخوانی دستور "window.location.href  = "/new/page/path انجام دهید.
- چرا این راه حل عمومی است؟ چون قسمت
  $.ajax({
                headers: { 'Authorization': 'Bearer ' + jwtToken },
توسط مرورگرها توسط یک post-back ساده (مانند لاگین معمولی در صفحات مبتنی بر Razor)، به سمت سرور ارسال نمی‌شود. مرورگرها فقط کوکی‌ها را به صورت خودکار ارسال می‌کنند و نه توکن‌های سفارشی را. بنابراین اگر حتی از این روش JWT در برنامه‌های MVC هم استفاده کنید، مجبور به استفاده‌ی از Ajax خواهید بود تا هدرهای سفارشی را بتوانید به سمت سرور، جهت بررسی و اعتبارسنجی نهایی ارسال کنید. قسمتی از عملیات Ajax هم بررسی شکست عملیات و واکنش نشان دادن به status code دریافتی است.
نظرات مطالب
React 16x - قسمت 26 - احراز هویت و اعتبارسنجی کاربران - بخش 1 - ثبت نام و ورود به سیستم
- باید؟ خیر. در اینجا فقط access token ارسال شده. قسمت refresh token پیاده سازی نشده. این مورد اختیاری هست و کار آن پیاده سازی sliding expiration هست. خیلی‌ها چنین قابلیتی را پیاده سازی نمی‌کنند و فقط به همان absolute expiration ارائه شده توسط access token اکتفا می‌کنند.
- زمانیکه با JWT کار می‌کنید، کوکی تولید نمی‌شود. اطلاعات بیشتر
در آن مطلب، کوکی برای پیاده سازی anti forgery token بوده که در اینجا پیاده سازی نشده.
- سایر سؤالات شما در قسمت‌های بعدی «احراز هویت و اعتبارسنجی کاربران» این سری بررسی شده‌اند که شامل ارسال خودکار access token به سمت سرور هم هست. بدون آن this.User.Identity وجود نخواهد داشت.

پیاده سازی این سری مستقل هست از ماخذ دومی که ذکر شده و بر اساس آن نیست و فقط نکات اساسی و مهم ذکر شده‌اند. کدهای کامل و مرتبط با این سری، ذیل هر قسمت پیوست شده.
نظرات مطالب
اعتبارسنجی در Angular 2 توسط JWT
با سلام
 بنده در پروژه Angular 7 ا برای احراز هویت نیز از Owin-JWT استفاده می‌کنم. سمت سرور نیز WebAPI  می‌باشد که در IIS هاست شده است. با استفاده از این روش متاسفانه مشکل حل نشد. مجبور شدم از Attribute به شکل زیر بروی Controller‌ها استفاده کنم :
   [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class ApiSettingsController : ApiBase
    {
    }

 بر روی Controller‌های WebAPI استفاده کردم و به سختی بالاخره مشکل حل شد. همچنین برای Owin به دلیل اینکه Controller خاصی نداره از روش زیر  استفاده کرده ام:
 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
             context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
        }

تا اینجا مشکل حل شده اما برای Refresh Token هر کاری میکنم خطای CORS رو میگیرم. شکل کار نیز به شکل زیر است:
public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
        {
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
        }
متاسفانه خیلی وقت گرفته تا الان اما مشکل حل نمیشه. در صورت امکان راهنمایی بفرمایید. 
درصورت نیاز کدهای بیشتری قرار بدم اینجا.
باتشکر

نظرات مطالب
روش استفاده‌ی صحیح از HttpClient در برنامه‌های دات نت
ممنونم از مطلب خوبتون
بنده در پروژه‌ی خودم لایه‌ی سرویس رو با Web Api پیاده سازی کردم، لایه‌ی اپلیکیشن با MVC
احراز هویت در لایه‌ی سرویس با JWT انجام می‌شود و نیاز است تا token دریافتی در DefaultRequestHeaders.Authorization تنظیم شود و سپس درخواست HTTP ارسال شود.( این موضوع در MVC انجام می‌پذیرد.)
با توجه به گفته‌ی خودتون Thread Safe ،DefaultRequestHeaders نیست. پس نمیتونم به ازای تمامی درخواست‌ها از یک HttpClient استفاده کنم و مجبورم به ازای هرکاربر HttpClient جدیدی ایجاد کنم تا token در header رو برای هر کاربر جداگانه تنظیم کنم.
پس کلید دیکشنری رو از Uri baseAddress به string token تغییر دادم.
حالا مشکلی که برام پیش اومده اینه که تعداد HttpClient‌های منقضی شده در دیکشنری زیاد میشه و باید با روشی اونها رو از دیکشنری حذف کنم که سعی میکنم حلش کنم اما سوالم اینه که:
آیا تغییری که در کلاس شما دادم اصولی بود ؟ 
پروژه‌ها
CorMon: سیستم مدیریت محتوای مبتنی بر ASP.NET Core و MongoDB

توضیح 

پروژه‌ی CorMon یک CMS رایگان و سورس باز برپایه ی ASP.NET Core و MongoDB می‌باشد که سورس آن را بر روی Github میتوانید دنبال کرده و در صورت تمایل در توسعه آن مشارکت داشته باشید.
هدف
این پروژه در اصل تلاش و تمرینی است برای اینکه چگونه یک پروژه را در بستر ASP.NET Core  پیاده کنیم و آن را با دیتابیس‌های NoSQL از جمله MongoDB و Redis به کار بگیریم.
معماری
معماری این پروژه تا حدود زیادی برگرفته از Onion Architecture و نیز ASP.NET Boilerplate می‌باشد و تا حد امکان طراحی آن ساده و خوانا در نظر گرفته شده تا مشارکت در توسعه و یا استفاده از آن راحت باشد.
ویژگی ها
در اینجا بخشی از ویژگی‌های این پروژه را مشاهده میکنید که به ترتیب در حال اجرا هستند :
- استفاده از دیتابیس MongoDB
- پیاده سازی Redis Cache
- استفاده از الگوی ریپازیتوری
- استفاده از ابزار DI پیش فرض
- پیاده سازی REST API
- پیاده سازی JWT
- پیاده سازی ASP.NET Identity با پروایدر Mongo
- پیاده سازی Unit Testing 
- پیاده سازی  Automated UI Testing با Selenium
و ...
تصاویر

مطالب
به دام انداختن خطاهای مدیریت نشده در برنامه‌های Windows forms دات نت

شبیه به نحوه‌ی به دام انداختن خطاهای مدیریت نشده در Web forms و روال استاندارد Application_Error ، در برنامه‌های Windows forms نیز این امر به صورت زیر ممکن است:


using System;
using System.Threading;
using System.Windows.Forms;

namespace testWinForms87
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// handling UI thread exceptions
Application.ThreadException += uIThreadException;

// force all Windows Forms errors to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

// handling non-UI thread exceptions.
AppDomain.CurrentDomain.UnhandledException += currentDomainUnhandledException;


Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

private static void currentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show(((Exception)e.ExceptionObject).Message, "currentDomainUnhandledException");
}

private static void uIThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "uIThreadException");
}
}
}

چند نکته:
الف)همانطور که ملاحظه می‌کنید سطرهای فوق باید قبل از Application.Run در روال اصلی برنامه تعریف شوند.
ب) این متدها استاتیک هستند و توصیه شده است در پایان برنامه ارجاعات آنها را حذف کنید تا نشتی حافظه رخ ندهد. دقیقا به همین صورت =+ که اضافه شدند با =- هم قابل حذف هستند.
ج) در حالت اجرا شدن uIThreadException ، برنامه بسته نخواهد شد (و بدیهی است در صورت عدم بکار گیری این روش، حتما برنامه کرش خواهد کرد). برای مثال شاید علاقمند نباشید که بخاطر عدم دسترسی نوشتن در پوشه‌ای خاص، خطای حاصل سبب بسته شدن کل برنامه شود. به این صورت این موارد را می‌توان به دام انداخت. اما currentDomainUnhandledException که حاصل از خطاهای ایجاد شده برای مثال در یک ترد دیگر بجز ترد اصلی برنامه هستند، حتما سبب بسته شدن برنامه خواهند شد. بنابراین اینجا تنها شانس لاگ کردن خطای مدیریت نشده حاصل را خواهیم داشت. به همین منظور همیشه توصیه می‌شود که در تردهای ایجاد شده در برنامه، حتما موارد مدیریت خطاها را لحاظ نمائید، زیرا خطاهای حاصل شده در آن‌ها غیرقابل اغماض بوده و حتما سبب کرش برنامه می‌شوند.

پ.ن.
دقیقا در برنامه‌های Win32 دلفی هم چنین قابلیتی به همین شکل و تقریبا با همین نام‌ها وجود دارد. فقط کافی است روالی را جهت Application.OnException ایجاد کنید: ;)

procedure TmyFrmMain.FormCreate(Sender: TObject);
begin
Application.OnException := MyExceptionHandler;
end;
procedure TmyFrmMain.MyExceptionHandler(Sender: TObject; E: Exception);
begin
ShowMessage(e.Message);
end;