স্বাগতম! আমরা এখন আপনার কোর্সের Section 20 (Filters)-এর “Authorization Filter” (লেকচার ২৯৬) টপিকে আছি।

যেকোনো ওয়েব অ্যাপ্লিকেশনের সবচেয়ে গুরুত্বপূর্ণ অংশ হলো সিকিউরিটি বা নিরাপত্তা। কে কোন পেজে ঢুকতে পারবে আর কে পারবে না, তা চেক করার জন্যই আমরা Authorization Filter ব্যবহার করি। Filter Pipeline-এর একেবারে শুরুতেই এটি বসে থাকে, যাতে কোনো আনঅথরাইজড ইউজার রিকোয়েস্ট করলে তাকে শুরুতেই আটকে দেওয়া যায়। চলুন, বিস্তারিত শিখি!


📝 Quick Revision Summary

ভবিষ্যতে দ্রুত রিভিশনের জন্য আজকের লেকচারের মূল পয়েন্টগুলো নিচে দেওয়া হলো:

  • Position in Pipeline: Authorization Filter হলো Filter Pipeline-এর প্রথম ফিল্টার। এটি মডেল বাইন্ডিং বা অন্য যেকোনো ফিল্টারের আগেই কাজ করে।

  • The Goal: এর মূল কাজ হলো রিকোয়েস্টকারী ইউজারের লগইন স্ট্যাটাস (Authentication) এবং পারমিশন (Authorization) চেক করা।

  • Authentication vs Authorization:

  • Authentication: ইউজার কে? (যেমন: ইউজার কি লগইন করেছে?)

  • Authorization: ইউজারের কি এই কাজ করার পারমিশন আছে? (যেমন: সাধারণ ইউজার কি এডমিন প্যানেলে ঢুকতে পারবে?)

  • Short-circuiting: যদি ইউজারের পারমিশন না থাকে, তবে context.Result = new StatusCodeResult(401); দিয়ে রিকোয়েস্টটিকে অ্যাকশন মেথডে যাওয়ার আগেই বাতিল করে দেওয়া হয়।

  • Cookies: সার্ভার থেকে ব্রাউজারে কুকি পাঠাতে Response.Cookies.Append() এবং ব্রাউজার থেকে আসা কুকি রিড করতে Request.Cookies ব্যবহার করা হয়।


🔍 Comprehensive Breakdown

১. Why Authorization Filter? [Priority: 10/10]

The “Why”: ধরুন, আপনার অ্যাপ্লিকেশনে একটি Inbox পেজ আছে। আপনি চান শুধুমাত্র লগইন করা ইউজাররাই যেন এই পেজটি দেখতে পারে। এখন কেউ যদি ব্রাউজারে সরাসরি yourwebsite.com/inbox লেখে, তবে তাকে তো পেজটি দেখতে দেওয়া যাবে না! তাকে আটকে দেওয়ার এই সিকিউরিটি চেকটি আমরা Controller-এর Action Method-এ করতে পারি। কিন্তু যদি আপনার এমন ১০০টি পেজ থাকে, তবে সব পেজে চেক করা বিরক্তিকর। তাই আমরা Pipeline-এর একদম শুরুতেই Authorization Filter বসিয়ে দিই।

২. Creating the Authorization Filter [Priority: 10/10]

Authorization Filter-এ শুধুমাত্র একটি মেথড থাকে: OnAuthorization (সিঙ্ক্রোনাসের জন্য) বা OnAuthorizationAsync (অ্যাসিন্ক্রোনাসের জন্য)। এই লেকচারে সিঙ্ক্রোনাস ভার্সন দেখানো হয়েছে।

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
 
public class TokenAuthorizationFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // ১. চেক করা হচ্ছে রিকোয়েস্টে 'AuthCookie' নামের কুকিটি আছে কিনা
        if (!context.HttpContext.Request.Cookies.ContainsKey("AuthCookie"))
        {
            // যদি না থাকে, তবে Short-circuit করে 401 Unauthorized পাঠানো হচ্ছে
            context.Result = new StatusCodeResult(401);
            return;
        }
 
        // ২. যদি কুকি থাকে, তবে তার ভ্যালু চেক করা হচ্ছে
        var cookieValue = context.HttpContext.Request.Cookies["AuthCookie"];
        
        // (রিয়েল ওয়ার্ল্ডে এখানে টোকেন বা ডেটাবেস চেক করা হয়, তবে এখানে ডেমোর জন্য হার্ডকোড করা হয়েছে)
        if (cookieValue != "A100")
        {
            // ভ্যালু না মিললে 401 Unauthorized
            context.Result = new StatusCodeResult(401);
            return;
        }
 
        // যদি সব ঠিক থাকে, তবে context.Result-এ কিছু অ্যাসাইন করা হচ্ছে না। 
        // ফলে রিকোয়েস্ট নরমালি সামনের দিকে (Model Binding, Action Filter) এগিয়ে যাবে।
    }
}
 

💡 Rule of Thumb: Authorization Filter-এর ভেতরে কখনোই Exception থ্রো (throw) করা উচিত নয়। কারণ, Exception Filter সাধারণত এররগুলো ধরে, কিন্তু Authorization Filter Exception Filter-এরও আগে এক্সিকিউট হয়। তাই এখানে এরর হলে অ্যাপ্লিকেশন সরাসরি ক্র্যাশ করতে পারে।

Authorization Filter তো কুকি খুঁজছে, কিন্তু কুকিটি ব্রাউজারে পাঠাবে কে? লেকচারার এর জন্য একটি ResultFilter তৈরি করেছেন, যা EditHttpGet পেজ লোড হওয়ার সময় সার্ভার থেকে ব্রাউজারে একটি কুকি সেট করে দেবে।

public class TokenResultFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        // সার্ভার থেকে ব্রাউজারে কুকি পাঠানোর জন্য Response.Cookies ব্যবহার করা হয়
        context.HttpContext.Response.Cookies.Append("AuthCookie", "A100");
    }
 
    public void OnResultExecuted(ResultExecutedContext context) { }
}
 

কী ঘটছে এখানে?

  1. ইউজার যখন Edit পেজে যায়, তখন TokenResultFilter ব্রাউজারে AuthCookie=A100 পাঠিয়ে দেয়।
  2. ব্রাউজার সেটি সেভ করে রাখে (Chrome Developer Tools-এর Application ট্যাব থেকে দেখা যায়)।
  3. এরপর ইউজার যখন ফর্ম সাবমিট করে (EditHttpPost), তখন ব্রাউজার নিজে থেকেই ওই কুকিটি সার্ভারে পাঠিয়ে দেয়।
  4. তখন সার্ভারে বসে থাকা TokenAuthorizationFilter সেই কুকিটি (Request.Cookies) রিড করে এবং ইউজারকে পাস করতে দেয়।

৪. Applying the Filters [Priority: 9/10]

Controller-এর নির্দিষ্ট অ্যাকশনে এই ফিল্টারগুলো বসিয়ে দেওয়া হয়েছে:

public class PersonsController : Controller
{
    // পেজ লোড হওয়ার সময় কুকি সেট করবে
    [TypeFilter(typeof(TokenResultFilter))] 
    public IActionResult Edit(int id) { ... }
 
    // ফর্ম সাবমিট করার সময় কুকি ভ্যালিডেট করবে
    [TypeFilter(typeof(TokenAuthorizationFilter))] 
    [HttpPost]
    public IActionResult Edit(PersonUpdateRequest personRequest) { ... }
}
 

🚀 Best Practices & .NET Modern Updates

Best Practices for Authorization:

  1. Don’t Roll Your Own Security: লেকচারার স্পষ্ট বলে দিয়েছেন, কুকির ভেতরে এভাবে হার্ডকোডেড ভ্যালু (যেমন A100) দিয়ে সিকিউরিটি চেক করাটা শুধু ডেমোনস্ট্রেশনের জন্য। রিয়েল-ওয়ার্ল্ড প্রোজেক্টে আমরা এভাবে সিকিউরিটি বানাই না।
  2. Use Built-in Features: ASP.NET Core-এ সিকিউরিটির জন্য নিজস্ব শক্তিশালী মেকানিজম (যেমন: Identity, JWT, Policy-based Authorization) আছে। সেখানে আমরা এই কাস্টম ফিল্টারের বদলে সরাসরি [Authorize] অ্যাট্রিবিউট ব্যবহার করি। (যা আপনার কোর্সের Identity সেকশনে বিস্তারিত শেখানো হবে)।

.NET 10 & Modern Context: .NET 10-এও Authorization-এর কনসেপ্ট একই। [Authorize] অ্যাট্রিবিউট ব্যাকগ্রাউন্ডে একটি Authorization Filter হিসেবেই কাজ করে। Minimal APIs-এ আমরা চেইন কলিংয়ের মাধ্যমে অথরাইজেশন অ্যাড করি:

// Minimal API .NET 10 Style
app.MapPost("/api/persons/edit", (PersonUpdateRequest req) => 
{
    return Results.Ok("Updated!");
})
.RequireAuthorization(); // এটি ব্যাকগ্রাউন্ডে Authorization Filter-এর কাজ করে
 

আশা করি Authorization Filter এবং কুকি মেকানিজমের বেসিকটা আপনার কাছে ক্লিয়ার হয়েছে! পরবর্তী লেকচারে আমরা Exception Filter নিয়ে কাজ করব, যা অ্যাপ্লিকেশনে ক্র্যাশ হওয়া ঠেকানোর জন্য অপরিহার্য।