پیاده‌سازی معماری Zero Trust در سیستم‌های احراز هویت ASP.NET Core

توسط: محسن درم بخت | منتشر شده در 1405/04/25 | بازدید : 9 بار | زمان مطالعه : 15 دقیقه

در سال‌های گذشته، استراتژی سنتی امنیت شبکه‌ها بر اساس مدل «قلعه و خندق» (Castle-and-Moat) بنا شده بود. در این مدل، فرض بر این بود که تمام کاربران و دستگاه‌های داخل شبکه داخلی قابل اعتماد هستند و خطر اصلی فقط از بیرون شبکه است. با این حال، با گسترش رایانش ابری، دورکاری، سرویس‌های توزیع‌شده و میکروسرویس‌ها، مرزهای شبکه سنتی به طور کامل از بین رفته‌اند. امروزه، بخش عمده‌ای از تهدیدات امنیتی از درون شبکه‌ها یا از طریق حساب‌های کاربری نشت‌یافته (Compromised Credentials) رخ می‌دهد. در پاسخ به این چالش‌ها، مفهوم جدیدی به نام معماری صفر مطلق یا Zero Trust شکل گرفته است.

اصل اساسی معماری Zero Trust بر این شعار تکیه دارد: «هیچ‌وقت اعتماد نکن، همیشه تایید کن» (Never Trust, Always Verify). در این معماری، هیچ کاربر، دستگاه یا سرویسی – چه در داخل شبکه محلی باشد و چه در خارج آن – به طور پیش‌فرض قابل اعتماد نیست. در این مقاله جامع، اصول Zero Trust را بررسی کرده و نحوه پیاده‌سازی گام‌به‌گام و عملیاتی آن را در چارچوب محبوب و قدرتمند ASP.NET Core آموزش خواهیم داد. همچنین بررسی خواهیم کرد که چگونه با استفاده از سیاست‌های دسترسی پویا و اعتبارسنجی مستمر، می‌توانیم امنیت نرم‌افزار خود را به سطح سازمان‌های بزرگ ارتقا دهیم.

اصول سه‌گانه معماری Zero Trust

معماری امنیتی Zero Trust بر پایه سه اصل اساسی بنا شده است که هر کدام نقش حیاتی در تغییر فلسفه امنیت وب ایفا می‌کنند:

  • تایید صریح و مستمر (Verify Explicitly): همیشه بر اساس تمام داده‌های در دسترس، کاربر را احراز هویت و دسترسی او را تایید کنید. این داده‌ها شامل هویت کاربر، موقعیت جغرافیایی، وضعیت سلامت دستگاه، نوع سرویس، و رفتارهای مشکوک یا ناهنجاری‌ها می‌شود.
  • استفاده از حداقل سطح دسترسی (Least Privilege Access): دسترسی کاربران را با استفاده از مکانیزم‌های دسترسی پویا (Just-In-Time) و دسترسی به اندازه کافی (Just-Enough-Access) محدود کنید تا در صورت نشت اطلاعات، خسارت به حداقل برسد.
  • فرض بر رخ دادن نشت امنیتی (Assume Breach): همیشه فرض کنید که مهاجمان به درون سیستم نفوذ کرده‌اند. شبکه را به بخش‌های کوچک‌تر تقسیم (Micro-segmentation) کرده، ارتباطات را رمزنگاری کنید و از سیستم‌های مانیتورینگ بلادرنگ برای کشف تهدیدات استفاده کنید.

تفکیک میکروسکوپی شبکه (Micro-segmentation) به ما اجازه می‌دهد که حتی در صورت نفوذ مهاجم به یک لایه یا یک سرویس خاص، او نتواند به صورت عرضی به سایر بخش‌های حساس شبکه حرکت کند. برای مثال، اگر یک برنامه وب‌سایت عمومی هک شود، مهاجم نباید به پایگاه داده اصلی یا سرویس مالی دسترسی داشته باشد، مگر اینکه به صورت صریح احراز هویت شده و دسترسی او توسط لایه‌های کنترلی صادر شده باشد.

تغییر جهت به سمت این اصول، نیازمند بازنگری در ساختارهای سنتی توسعه وب است که در مقالاتی مانند افزایش امنیت برنامه‌های وب با ASP.NET Core به اصول پایه‌ای آن اشاره شده است. در Zero Trust، ما احراز هویت را یک‌بار انجام نمی‌دهیم، بلکه در طول هر درخواست و تعامل، آن را مورد بررسی قرار می‌دهیم.

جریان احراز هویت در معماری Zero Trust

در مدل سنتی، کاربر پس از یک‌بار ورود موفق، یک توکن دریافت می‌کرد و تا انقضای آن توکن، بدون بررسی مجدد می‌توانست درخواست ارسال کند. اما در مدل Zero Trust، هر درخواست کاربر به لایه API Gateway یا پایپ‌لاین احراز هویت نرم‌افزار هدایت شده و علاوه بر بررسی اعتبار توکن، مواردی مانند آی‌پی درخواست‌دهنده، اثر انگشت مرورگر (Browser Fingerprint)، و حتی رفتارهای اخیر کاربر سنجیده می‌شود. نمودار زیر جریان کاری این اعتبارسنجی مستمر را نشان می‌دهد:

مراحل احراز هویت در معماری Zero Trust

پیاده‌سازی گام‌به‌گام Zero Trust در ASP.NET Core

برای پیاده‌سازی اصول Zero Trust در پروژه‌های دات‌نت، نیاز داریم تا سیستم‌های احراز هویت و اعتبارسنجی را به لایه‌های مختلف پایپ‌لاین برنامه متصل کنیم. دات‌نت به لطف سیستم منعطف سرویس‌ها و میان‌افزارها، بهترین ابزارها را برای این کار در اختیار ما قرار می‌دهد. اگر با ساختار پایپ‌لاین دات‌نت آشنا نیستید، مطالعه مقاله آشنایی با مفهوم میان‌افزار و سرویس در asp.net core به شما کمک شایانی خواهد کرد.

گام اول: احراز هویت قوی مبتنی بر چندعاملی (MFA) و تایید مستمر Claims

اولین گام در تایید هویت، استفاده از مکانیزم‌های احراز هویت چندعاملی است. علاوه بر تایید اولیه، توکن‌های صادر شده باید مدام اعتبارسنجی شوند. برای مثال، اگر نقش کاربر در دیتابیس تغییر کند یا حساب کاربری او غیرفعال شود، نباید تا انقضای توکن JWT منتظر بمانیم. برای حل این مشکل، یک میان‌افزار سفارشی (Custom Middleware) یا فیلتر اختصاصی جهت تایید اعتبار مستمر Claims طراحی می‌کنیم.

using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Threading.Tasks;

public class SecurityStampValidatorMiddleware
{
    private readonly RequestDelegate _next;

    public SecurityStampValidatorMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, IUserService userService)
    {
        if (context.User.Identity != null && context.User.Identity.IsAuthenticated)
        {
            var userId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            var securityStamp = context.User.FindFirst("SecurityStamp")?.Value;

            // بررسی وضعیت کاربر در دیتابیس یا کش به صورت زنده
            var isValid = await userService.ValidateSecurityStampAsync(userId, securityStamp);

            if (!isValid)
            {
                // در صورت تغییر نقش یا غیرفعال شدن حساب، بلافاصله دسترسی قطع می‌شود
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                await context.Response.WriteAsync("توکن شما دیگر معتبر نیست و باید دوباره وارد شوید.");
                return;
            }
        }

        await _next(context);
    }
}

با رجیستر کردن این میان‌افزار در فایل Program.cs، تضمین می‌کنیم که در هر درخواست، وضعیت فعلی کاربر به طور زنده با سیستم مرکزی هماهنگ می‌شود و فرض اعتماد پیش‌فرض به توکن‌های صادر شده از بین می‌رود.

گام دوم: کنترل دسترسی مبتنی بر سیاست‌های پویا (Policy-Based Authorization)

یکی دیگر از اصول Zero Trust، دسترسی بر اساس کمترین امتیاز است. تعریف نقش‌های ساده مانند "Admin" یا "User" برای سیستم‌های پیچیده پاسخگو نیست. ما باید از سیاست‌های دسترسی پویا استفاده کنیم که شرایط محیطی کلاینت را در تصمیم‌گیری‌های امنیتی دخالت دهند. به عنوان مثال، دسترسی به بخش مدیریت مالی فقط در ساعات اداری و با آی‌پی‌های مجاز شرکت امکان‌پذیر باشد.

برای پیاده‌سازی این سناریو، ابتدا یک Requirement سفارشی تعریف می‌کنیم:

using Microsoft.AspNetCore.Authorization;
using System;

public class OfficeHoursAndIpRequirement : IAuthorizationRequirement
{
    public string AllowedIpRange { get; }

    public OfficeHoursAndIpRequirement(string allowedIpRange)
    {
        AllowedIpRange = allowedIpRange;
    }
}

در ادامه، یک Handler برای ارزیابی این شرط و گرفتن تصمیم نهایی طراحی می‌کنیم:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System;
using System.Threading.Tasks;

public class OfficeHoursAndIpHandler : AuthorizationHandler
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public OfficeHoursAndIpHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OfficeHoursAndIpRequirement requirement)
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext == null)
        {
            context.Fail();
            return Task.CompletedTask;
        }

        // بررسی آی‌پی کلاینت
        var clientIp = httpContext.Connection.RemoteIpAddress?.ToString();
        
        // بررسی زمان درخواست (ساعات اداری)
        var currentTime = DateTime.Now.TimeOfDay;
        var start = new TimeSpan(8, 0, 0); // 8:00 AM
        var end = new TimeSpan(17, 0, 0);  // 5:00 PM

        if (clientIp == requirement.AllowedIpRange && currentTime >= start && currentTime <= end)
        {
            context.Succeed(requirement);
        }
        else
        {
            // در غیر این صورت، حتی با داشتن نقش ادمین، دسترسی رد می‌شود
            context.Fail();
        }

        return Task.CompletedTask;
    }
}

حالا باید این سیاست را در فایل Program.cs تعریف کنیم:

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<IAuthorizationHandler, OfficeHoursAndIpHandler>();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("StrictZeroTrustPolicy", policy =>
        policy.Requirements.Add(new OfficeHoursAndIpRequirement("192.168.1.100")));
});

سپس با قرار دادن اتریبیوت [Authorize(Policy = "StrictZeroTrustPolicy")] بر روی کنترلرها، این سیاست امنیتی سخت‌گیرانه را اعمال می‌کنیم. این معماری به جداسازی دقیق وظایف امنیتی کمک کرده و تطابق کاملی با مفاهیم مطرح شده در مقاله معماری Clean در ASP.NET Core دارد، جایی که منطق امنیت از لایه‌های اصلی کسب‌وکار جدا نگه‌داشته می‌شود.

گام سوم: بررسی سلامت و اعتبار دستگاه کلاینت (Device Health Attestation)

در Zero Trust، صرف داشتن رمز عبور و توکن معتبر کافی نیست، دستگاهی که درخواست را ارسال می‌کند نیز باید تایید صلاحیت شود. در اپلیکیشن‌های تحت وب و APIها، می‌توانیم با پیاده‌سازی مکانیزم‌های بررسی گواهی‌نامه کلاینت (Client Certificates) و بررسی هدرهای امنیتی، وضعیت سیستم کلاینت را بسنجیم. کد زیر نحوه فعال‌سازی اعتبارسنجی گواهی‌نامه کلاینت را در دات‌نت نشان می‌دهد:

using Microsoft.AspNetCore.Authentication.Certificate;
using System.Security.Cryptography.X509Certificates;

builder.Services.AddAuthentication()
    .AddCertificate(options =>
    {
        options.AllowedCertificateTypes = CertificateTypes.All;
        options.Events = new CertificateAuthenticationEvents
        {
            OnCertificateValidated = context =>
            {
                var validationService = context.HttpContext.RequestServices
                    .GetRequiredService();

                if (validationService.IsValid(context.ClientCertificate))
                {
                    context.Success();
                }
                else
                {
                    context.Fail("گواهی‌نامه کلاینت معتبر نبوده و مورد تایید سیستم Zero Trust نیست.");
                }

                return Task.CompletedTask;
            }
        };
    });

تکنیک‌ها و بهترین روش‌ها برای موفقیت در پیاده‌سازی Zero Trust

پیاده‌سازی Zero Trust فراتر از نوشتن چند خط کد است و نیازمند رعایت نکات فنی مهمی است:

  • تقسیم‌بندی خرد (Micro-segmentation): تا جای ممکن سرویس‌ها و دیتابیس‌های خود را از یکدیگر جدا کنید. ارتباط بین میکروسرویس‌ها را با پروتکل‌های امنی مانند mTLS (Mutual TLS) رمزنگاری کنید تا ارتباط بین سرویس‌ها نیز بدون احراز هویت انجام نشود.
  • پایش بلادرنگ و مانیتورینگ هوشمند: تمام لاگ‌ها، درخواست‌های ورودی و تغییرات وضعیت کاربران را در سیستم‌های متمرکز ذخیره و تحلیل کنید. رفتارهای غیرعادی مانند ورود از دو کشور مختلف در بازه زمانی کوتاه را کشف و مسدود سازید.
  • رمزنگاری جامع داده‌ها: داده‌ها هم در زمان انتقال (In-Transit) با پروتکل‌های TLS ۱.۳ و هم در زمان ذخیره‌سازی در دیتابیس (At-Rest) باید رمزنگاری شوند تا مهاجمان در صورت عبور از سدهای دفاعی، به دیتای خام دسترسی نداشته باشند.

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

معماری Zero Trust دیگر یک انتخاب نیست، بلکه ضرورتی برای مقابله با تهدیدات سایبری در برنامه‌های وب امروزی است. با به‌کارگیری اصول تایید صریح، حداقل دسترسی و فرض بر وقوع نشت، و پیاده‌سازی آن‌ها به کمک ابزارهای غنی دات‌نت مانند سیاست‌های دسترسی سفارشی، میان‌افزارها و احراز هویت مبتنی بر گواهی‌نامه، می‌توانید یک سیستم پایدار و کاملاً امن طراحی کنید. برای شروع و یادگیری پایه چارچوب دات‌نت، حتماً با مفاهیم موجود در مقاله آشنایی با asp.net core - مزایا و ویژگی‌ها آغاز کنید.

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

دوره‌های آنلاین برنامه‌نویسی لیست دوره‌ها