পাঠ ৩৯ · ৫৭-এর মধ্যে · মডিউল ৯
Home / Courses / Software Testing & Quality Assurance / অথেন্টিকেশন/অথোরাইজেশন

অথেন্টিকেশন ও অথোরাইজেশন টেস্টিং

Authentication and authorization testing
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • AuthN বনাম AuthZ-এর সুনির্দিষ্ট সংজ্ঞা এবং এই দুটো কেন ভিন্ন টেস্ট কেস দাবি করে
  • সাধারণ AuthN টেস্ট কেস (ভুল পাসওয়ার্ড, অস্তিত্বহীন ইউজার) বনাম সাধারণ AuthZ টেস্ট কেস (সঠিক লগইন কিন্তু ভুল পারমিশন)
  • "সঠিক-রোল-বনাম-ভুল-রোল" টেস্ট ডিজাইনের ধরন — M9/L36-এর ব্রোকেন অ্যাক্সেস কন্ট্রোল ক্যাটাগরির সরাসরি প্রয়োগ
  • একটি সত্যিকারের, চলমান unittest স্যুট — উভয় ধরনের কেস আলাদাভাবে পরীক্ষা করে

১ · AuthN বনাম AuthZ — দুটো ভিন্ন প্রশ্ন

Authentication (AuthN)Authenticationএকজন ব্যবহারকারী বা সিস্টেম আসলেই যা দাবি করছে তাই কি না তা যাচাই করা — সাধারণত ক্রেডেনশিয়াল (পাসওয়ার্ড, টোকেন) মিলিয়ে। এবং Authorization (AuthZ)Authorizationএকজন ইতিমধ্যে-প্রমাণিত (authenticated) ব্যবহারকারীর একটি নির্দিষ্ট কাজ করার অনুমতি আছে কি না তা যাচাই করা। — এই দুটো ধারণা প্রায়ই গুলিয়ে ফেলা হয়, কিন্তু টেস্টিং-এর দৃষ্টিকোণ থেকে এগুলো সম্পূর্ণ আলাদা প্রশ্ন, এবং ক্রমানুসারেও আলাদা: প্রথমে AuthN ("আপনি কে?"), তারপর AuthZ ("আপনি কি এটা করতে পারবেন?")।

লগইন চেষ্টা (ইউজারনেম + পাসওয়ার্ড) AuthN: "আপনি কে?" ক্রেডেনশিয়াল যাচাই AuthZ: "অনুমতি আছে?" রোল/পারমিশন যাচাই
AuthN ব্যর্থ হলে ব্যবহারকারী কখনোই AuthZ ধাপে পৌঁছায় না — কিন্তু AuthN পাস করার পরও AuthZ আলাদাভাবে ব্যর্থ হতে পারে, তাই দুটোর জন্যই আলাদা টেস্ট কেস প্রয়োজন।
সাধারণ AuthN টেস্ট কেস
ভুল পাসওয়ার্ড প্রত্যাখ্যাত হয় কি না, অস্তিত্বহীন ইউজারনেম প্রত্যাখ্যাত হয় কি না, এবং মেয়াদোত্তীর্ণ/অবৈধ টোকেন প্রত্যাখ্যাত হয় কি না।
সাধারণ AuthZ টেস্ট কেস
সঠিকভাবে লগইন করা একজন লো-প্রিভিলেজ ইউজার কি একটি হাই-প্রিভিলেজ কাজ (যেমন ডিলিট) করার চেষ্টা করলে প্রত্যাখ্যাত হয় — এখানে ক্রেডেনশিয়াল সঠিক, শুধু পারমিশন নেই।
কেন এই পার্থক্যটি গুরুত্বপূর্ণ (M9/L36-এর সাথে সম্পর্ক)

M9/L36-এ আলোচিত "ব্রোকেন অ্যাক্সেস কন্ট্রোল" ক্যাটাগরির বেশিরভাগ বাস্তব বাগ AuthN-এর সমস্যা নয় — AuthZ-এর সমস্যা। অর্থাৎ, ব্যবহারকারী সঠিকভাবেই লগইন করেছেন, কিন্তু সিস্টেম ভুলভাবে ধরে নিয়েছে "লগইন করা মানেই সব কিছুর অনুমতি আছে"। তাই একজন টেস্টার শুধু "ভুল পাসওয়ার্ডে লগইন ব্যর্থ হয়" পরীক্ষা করেই সন্তুষ্ট থাকতে পারেন না — "সঠিক লগইন কিন্তু ভুল পারমিশন" এই দৃশ্যকল্পও আলাদাভাবে পরীক্ষা করতে হবে।

২ · একটি সত্যিকারের রোল-বেসড পারমিশন টেস্ট স্যুট

নিচের কোড সেলে একটি সরল ইউজার/রোল/পারমিশন সিস্টেম আছে — authenticate() ক্রেডেনশিয়াল যাচাই করে (AuthN), আর authorize() একটি রোলের নির্দিষ্ট অ্যাকশন করার অনুমতি আছে কি না তা যাচাই করে (AuthZ)। একটি সত্যিকারের unittest.TestCase উভয় ধরনের কেস আলাদাভাবে পরীক্ষা করে।

Python
import unittest

USERS = {
    "alice": {"password": "hunter2", "role": "admin"},
    "bob": {"password": "letmein", "role": "editor"},
    "carol": {"password": "qazwsx", "role": "viewer"},
}

PERMISSIONS = {
    "admin": {"view", "edit", "delete", "manage_users"},
    "editor": {"view", "edit"},
    "viewer": {"view"},
}

def authenticate(username, password):
    """AuthN: ক্রেডেনশিয়াল সঠিক হলে রোল রিটার্ন করে, নাহলে None।"""
    user = USERS.get(username)
    if user is None or user["password"] != password:
        return None
    return user["role"]

def authorize(role, action):
    """AuthZ: একটি রোলের নির্দিষ্ট অ্যাকশন করার অনুমতি আছে কি না।"""
    return action in PERMISSIONS.get(role, set())

class AuthenticationTests(unittest.TestCase):
    # --- AuthN: "আপনি কে?" ---

    def test_correct_credentials_return_role(self):
        self.assertEqual(authenticate("alice", "hunter2"), "admin")

    def test_wrong_password_is_rejected(self):
        self.assertIsNone(authenticate("alice", "wrong-password"))

    def test_unknown_username_is_rejected(self):
        self.assertIsNone(authenticate("mallory", "anything"))

class AuthorizationTests(unittest.TestCase):
    # --- AuthZ: "আপনার অনুমতি আছে?" (ধরে নেওয়া হচ্ছে AuthN ইতিমধ্যে পাস হয়েছে) ---

    def test_admin_can_delete(self):
        self.assertTrue(authorize("admin", "delete"))

    def test_editor_cannot_delete(self):
        # সঠিক-রোল-স্বীকৃত, কিন্তু এই নির্দিষ্ট অ্যাকশনের অনুমতি নেই
        self.assertFalse(authorize("editor", "delete"))

    def test_viewer_can_view(self):
        self.assertTrue(authorize("viewer", "view"))

    def test_viewer_cannot_edit(self):
        self.assertFalse(authorize("viewer", "edit"))

suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(AuthenticationTests))
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(AuthorizationTests))
unittest.TextTestRunner(verbosity=2).run(suite)

    
লক্ষ্য করুন test_editor_cannot_delete কেসটি AuthN নয়, AuthZ পরীক্ষা করছে — bob (editor) সম্পূর্ণ বৈধভাবে লগইন করতে পারেন (ক্রেডেনশিয়াল সঠিক হলে), কিন্তু authorize("editor", "delete") এখনও False রিটার্ন করে কারণ PERMISSIONS["editor"] সেটে "delete" নেই। এটিই AuthN ও AuthZ-এর ব্যবহারিক পার্থক্য — একই ব্যবহারকারী, দুটো ভিন্ন প্রশ্নে দুটো ভিন্ন ফলাফল।
মূল কথা · Key takeaway

AuthN ও AuthZ আলাদা ব্যর্থতার মোড, তাই আলাদা টেস্ট কেস দরকার — "ভুল পাসওয়ার্ড প্রত্যাখ্যাত হয়" টেস্ট করলেই "সঠিক ইউজার কিন্তু ভুল পারমিশন প্রত্যাখ্যাত হয়" টেস্ট করা হয় না, এবং উল্টোটাও সত্য। একটি সম্পূর্ণ সিকিউরিটি টেস্ট স্যুটে উভয় ধরনের কেসই স্পষ্টভাবে থাকা প্রয়োজন — এটিই এই কোর্সের M2-এ শেখা "প্রতিটি ভিন্ন আচরণের জন্য একটি নির্দিষ্ট টেস্ট কেস" নীতিরই একটি সিকিউরিটি-নির্দিষ্ট প্রয়োগ।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ একজন টিম মেম্বার বলছেন, "আমরা তো লগইন টেস্ট করেছি, তাই সিকিউরিটি টেস্টিং শেষ" — এই দাবিতে কী সমস্যা আছে?

লগইন টেস্ট করা মানে শুধু AuthN টেস্ট করা — এটি নিশ্চিত করে ভুল ক্রেডেনশিয়াল প্রত্যাখ্যাত হচ্ছে, কিন্তু এটি একদমই বলে না যে সঠিকভাবে লগইন করা একজন ব্যবহারকারী শুধুমাত্র তার নিজের অনুমোদিত কাজগুলোই করতে পারছেন। AuthZ আলাদাভাবে পরীক্ষা না করলে ব্রোকেন অ্যাক্সেস কন্ট্রোলের মতো গুরুতর দুর্বলতা অধরা থেকে যেতে পারে।

প্র ০২ উপরের কোড সেলে যদি authorize()-এ একটি বাগ থাকত যেখানে অজানা রোলের জন্য PERMISSIONS.get(role, set())-এর বদলে PERMISSIONS.get(role, {"view", "edit", "delete"}) লেখা হতো, তাহলে কী সমস্যা হতো?

এটি একটি বিপজ্জনক "ফেইল-ওপেন" বাগ হতো — যদি কোনো কারণে একটি অজানা বা টাইপো-যুক্ত রোল নাম (authorize()-এ পাঠানো হয়), তাহলে ডিফল্ট হিসেবে সব অনুমতি দিয়ে দেওয়া হতো, বাস্তবে কোনো অনুমতিই না থাকার বদলে। এটি দেখায় কেন ডিফল্ট আচরণ সবসময় "সবচেয়ে কম অনুমতি" (fail-closed) হওয়া উচিত, "সবচেয়ে বেশি অনুমতি" (fail-open) নয় — একজন টেস্টারের এই ধরনের ডিফল্ট-আচরণ কেসও পরীক্ষা করা উচিত।

প্র ০৩ test_correct_credentials_return_role এবং test_admin_can_delete — এই দুটো টেস্ট আলাদা TestCase ক্লাসে রাখা হয়েছে কেন, একই ক্লাসে নয়?

কারণ এই দুটো ভিন্ন উদ্বেগ (concern) পরীক্ষা করছে — AuthenticationTests শুধু "ক্রেডেনশিয়াল সঠিকভাবে যাচাই হচ্ছে কি না" নিয়ে, আর AuthorizationTests শুধু "একটি রোলের সঠিক পারমিশন আছে কি না" নিয়ে। M3-এ শেখা "টেস্ট অর্গানাইজেশন" নীতি অনুযায়ী সম্পর্কিত টেস্টকে একসাথে গ্রুপ করা কোডকে পড়তে ও রক্ষণাবেক্ষণ করতে সহজ করে — একজন রিভিউয়ার ক্লাসের নাম দেখেই বুঝতে পারেন কোন ধরনের ব্যর্থতা কোথায় খুঁজতে হবে।

অনুশীলন

  1. চিন্তা করুন: PERMISSIONS-এ আর কোন কোন AuthZ টেস্ট কেস যোগ করা উচিত বলে আপনার মনে হয়? (হিন্ট: admin-এর manage_users পারমিশন এখনও টেস্ট করা হয়নি)

    যুক্তিসঙ্গত সংযোজন: self.assertTrue(authorize("admin", "manage_users")) এবং self.assertFalse(authorize("viewer", "manage_users")) — এই দুটো নিশ্চিত করবে সবচেয়ে সংবেদনশীল পারমিশনটি (ইউজার ম্যানেজমেন্ট) শুধু admin-এর জন্যই সীমাবদ্ধ, অন্য কোনো রোলের জন্য নয়।

  2. পরীক্ষা করুন: উপরের কোড সেলে PERMISSIONS["viewer"]-এ ভুলবশত "delete" যোগ করে (অর্থাৎ {"view", "delete"}) Run চেপে দেখুন কোন টেস্ট কেসটি এখন ব্যর্থ হয়।

    বর্তমান টেস্ট স্যুটে viewer-এর "delete" পারমিশন নেই তা যাচাই করার মতো কোনো টেস্ট নেই, তাই এই পরিবর্তনে বিদ্যমান কোনো টেস্ট সরাসরি ব্যর্থ হবে না — এটি নিজেই একটি গুরুত্বপূর্ণ শিক্ষা: টেস্ট কভারেজে ফাঁক থাকলে একটি গুরুতর AuthZ বাগও নীরবে পাস হয়ে যেতে পারে। এই ফাঁক বন্ধ করতে self.assertFalse(authorize("viewer", "delete"))-এর মতো একটি টেস্ট যোগ করলে তবেই এই পরিবর্তনটি ধরা পড়বে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ SDLC-তে সিকিউরিটি টেস্টিং এবং পরের মডিউলে অ্যাডভান্সড টেস্টিং টেকনিক — পরবর্তী পাঠগুলো।
  • Cybersecurity কোর্স সহোদর কোর্স অথেন্টিকেশন/অথোরাইজেশন সিস্টেমের টেকনিক্যাল ডিজাইন ও অ্যাটাক ভেক্টর সেই কোর্সে কভার করা হয়েছে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks, Mobile App Development, Ethics in Computing & AI Safety ও Software Testing & Quality Assurance — সব এক জায়গায়।
আগের পাঠ
ইনপুট ভ্যালিডেশন ও ইনজেকশন টেস্টিং