احراز هویت مبتنی بر Token در Net Core. و JWT

 Net Core. و JWT

در این مقاله راجب احراز هویت مبتنی بر Tokenدر Net Core. و JWT صحبت خواهیم کرد.همچنین نحوه‌ی بکارگیری token جهت دسترسی به منابع حفاظت شده را بیان خواهیم کرد.

این مقاله، نحوه‌ی ایجاد یک برنامه‌ی.Net Core و JWT  ( با استفاده از نشانه‌گذاری مبتنی بر JWT )  جهت احراز هویت یک کاربر را خواهیم دید.

در این مقاله، نحوه‌ی راه‌اندازی یک برنامه‌ی back end جهت اعتبارسنجی یک درخواست سرویس‌گیرنده از طریق نشانه‌گذاری و ایمن‌سازی یک نقطه‌ی پایانی که تنها توسط یک token معتبر قابل دسترسی باشد را نشان خواهیم داد.

از JWT JSON Web Token به عنوان یک استاندارد نشانه‌گذاری برای احراز هویت استفاده خواهیم کرد.

JWT یک استاندارد نشانه‌گذاری بسیار مشهور و مورد استفاده بطور گسترده است.

یک استاندارد باز (RFC 7519) بوده و اطلاعات دریافتی توسط آن مورد اعتماد است، چرا که بصورت دیجیتالی امضاء شده‌است.

نحوه‌ی کار آن را در این مقاله شرح خواهیم داد.

از .Net Core 2.1 برای فریمورک API استفاده خواهم کرد.

.Net Core و JWT

همانطور که می‌دانید، احراز هویت مبتنی بر token این روزها محبوب و رایج است. آیا ارزشش را دارد؟

برای پاسخ به این پرسش، نیاز است مفهوم احراز هویت مبتنی بر cookie را درک کنیم.

احراز هویت مبتنی بر cookie نیاز به یک سرویس‌گیرنده جهت فراهم کردن اعتبارنامه‌های معتبر (نام کاربری و رمزعبور) دارد.

سرور آن را اعتبارسنجی کرده و یک نشست ایجاد می‌کند و شناسه‌ی نشست را به سرویس‌گیرنده (جستجوگر) ارسال می‌کند.

سرور همچنین این شناسه‌ی نشست را در انباره‌ی خود ذخیره می‌کند تا بتواند دفعات بعدی آن را با هر درخواست ورودی مقایسه کند.

سرویس‌گیرنده این شناسه‌ی نشست را به عنوان یک cookie ذخیره کرده و آن را به درخواست منبع به سرور الصاق می‌کند.

احراز هویت

می‌توانید مشاهده کنید گه احراز هویت مبتنی بر cookie نیاز به یک سرور دارد تا بر همه‌ی نشست‌های فعال نظارت داشته باشد، این نشست‌ها با عنوان نشست‌های ” stateful ” شناخته می‌شوند.

هنگامی که شناسه‌ی نشست گم یا خراب شود، نیاز است یک نشست جدید ایجاد شود.

تصور کنید که یک سرویس‌گیرنده با چندین سرور منبع درگیر باشد! در این حالت، آن سرویس‌گیرنده باید cookie مربوط به هر یک از سرورها را به خاطر داشته و بر آنها نظارت داشته باشد.

متد مبتنی بر token، بر محدودیت‌های احراز هویت مبتنی بر cookie غلبه می‌کند.

در احراز هویت مبتنی بر token ، به سرویس‌گیرنده در عوض cookie ، token داده می‌شود.

Tokenها JSON سبک وزن هستند و حاوی اطلاعات کد گذاری شده در رابطه با کاربر و زمان انقضاء می‌باشند.

مزیت

سرور به جای ذخیره‌ی نشست‌ها برای هر سرویس‌گیرنده، تنها نیاز است نشانه‌ی درخواست ورودی را اعتبارسنجی کند.

بنابراین، بهترین گزینه برای پیاده‌سازی ” stateless “سرویس‌ها است، که گزینه‌ی مناسبی برای RESTful WebAPI می‌باشد.

.Net Core و JWT

JWT ) JSON Web Token ) فرمتی بسیار رایج از پیاده‌سازی مبتنی بر token می‌باشد.

هم‌اکنون آنقدر مشهور است که تبدیل به یک استاندارد بالفصل برای احراز هویت مبتنی بر token شده‌است.

JWT از سه جزء/کامپوننت تشکیل شده که توسط یک نقطه (.) از هم جدا شده‌اند.

احراز هویت

Header

Header حاوی اطلاعات استاندارد، یعنی نوع token و نام الگوریتم است. اطلاعات در فرمت base64 کدگذاری می‌شوند.

مثال:

{  
   "alg": "HS256",  
   "typ": "JWT"  
}  

Payload 

Payload داده‌های JSON است که حاوی اطلاعات کاربر است.

می‌تواند اما نیاز نیست محدود به داده‌های مرتبط با کاربر باشد، claim ها و هر داده‌ی مورد نیاز دیگری نیز می‌تواند در آن باشد.

مثال:

{  
   “issuer”: “http://www.exampleweb.com”,  
   “expires”: “۲۰۱۵-۱۱-۱۸T18:25:43.511Z”  
}  

Signature 

Signature یک ” امضای دیجیتالی” از ترکیب header و payload است.

Signature به سرور کمک می‌کند تا صحت محتوای JWT را در برابر تغییر مخرب محتوا تایید کند.

Token

پیاده‌سازی

بیایید این مفهوم را از طریق ASP .NET Core پیاده‌سازی کنیم.

Visual Studio را باز کرده و .Net Core-> ASP.NET Core Web Application را انتخاب کنید.

Token

نوع پروژه‌ی “API” را انتخاب کنید …

برنامه را اجرا کرده و احتمالا این خروجی را دریافت خواهید کرد.

احراز هویت مبتنی بر Token

این نشان می‌دهد که GET در کنترل‌کننده‌ی ” values ” برای هدر باز است.

هیچ‌گونه محدودیت و مانعی وجود ندارد. بیایید فرض کنیم سناریویی داریم که تنها کاربران احراز هویت شده می‌توانند به این URL دسترسی یابند.

برای پنهان‌کردن آن از دید عموم و در دسترسی کاربر احراز شده قرار گرفتن، آن را با صفت ” Authorize ” تزیین می‌کنم.

احراز هویت مبتنی بر Token

همچنین، احراز هویت را به HTTP Request Pipeline (خط لوله‌ی درخواست HTTP) اضافه می‌کنم.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
{  
.  
.  
.  
app.UseAuthentication();   
app.UseMvc();  
}  

اکنون، اگر بخواهید به این پایانه دسترسی پیدا کنید، احتمالا این خطا را دریافت می‌کنید.

احراز هویت مبتنی بر Token

بیان می‌کند که (پیاده‌سازی ضعیف مدیریت خطا را نادیده بگیرید) URL را تنها در اختیار کاربران احراز شده قرار می‌دهیم.

بسیار عالی، بخش ایمن‌سازی منبع به تمام رسیده‌است.

بعد از آن ، به مکانیزمی برای تولید یک token برای کاربران معتبر نیاز داریم.

برای این کار، یک کنترل‌کننده، AuthController، اضافه خواهیم کرد که اعتبارنامه‌های ورود به سیستم (نام کاربری و رمز عبور) را جذب، کاربر را اعتبارسنجی و یک token تولید خواهد کرد.

برای این کار، یک کلاس مدل ” LoginModel ” جهت نگهداری ” UserName ” و ” Password ” و یک کنترل‌کننده‌ی جدید ” AuthController ” اضافه کنید.

 Token در Net Core. و JWT

این کد را به “LoginModel” اضافه کنید.

public class LoginModel  
{  
    public string UserName { get; set; }  
    public string Password { get; set; }  
}  

این کد را در “AuthController” اضافه کنید.

Route("api/[controller]")]  
    [ApiController]  
    public class AuthController : ControllerBase  
    {  
        // GET api/values  
        [HttpPost, Route("login")]  
        public IActionResult Login([FromBody]LoginModel user)  
        {  
            if (user == null)  
            {  
                return BadRequest("Invalid request");  
            }  
              
            if (user.UserName == "johncitizen" && user.Password == "abc@123")  
            {  
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("KeyForSignInSecret@1234"));  
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);  
  
                var tokeOptions = new JwtSecurityToken(  
                    issuer: "http://localhost:2000",  
                    audience: "http://localhost:2000",  
                    claims: new List<Claim>(),  
                    expires: DateTime.Now.AddMinutes(30),  
                    signingCredentials: signinCredentials  
                );  
  
                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);  
                return Ok(new { Token = tokenString });  
            }  
            else  
            {  
                return Unauthorized();  
            }  
        }  
    }  

همانطور که می‌توانید ببینید، ” AuthController ” دارای یک عمل ورود به سیستم است که به ” LoginModel ” به عنوان ورودی برای نام‌کاربری و رمزعبور احتیاج دارد.

عمل ورود، کاربر را با نام‌کاربری و رمز عبور کدگذاری اختصاصی‌شده اعتبارسنجی می‌کند (جهت سادگی، گرچه این اعتبارسنجی در عمل باید از طریق پایگاه‌داده انجام شود).

این عمل  token، token را تولید و در صورتیکه اعتبارنامه‌ها معتبر باشند، به سرویس‌گیرنده ارسال می‌کند.

اگر اعتبارنامه‌ها مطابقت نداشته باشند، خطای ” unauthorized ”  ارسال خواهد کرد.

اگر از نزدیک به ساختار token نگاه کنید، حاوی برخی اطلاعات مورد نیاز است.

دارای issuer، audience ، claim ها، و زمان انقضاء می‌باشد که بخشی از payload است.

” JwtSecurityTokenHeader ” مراقب افزودن Header و یک Signature است.

توجه داشته باشید که لیست Claim ها خالی است، چرا که من در این مقاله، تایید مبتنی بر نقش را پیاده‌سازی نمی‌کنم.

در اینجا، پیاده‌سازی بخش تولید و ارسال token را کامل کرده‌ایم.

.Net Core و JWT

بیایید این برنامه را بیازماییم. از ابزار ” Postman ” برای دسترسی به ” Login “، ارسال اعتبارنامه‌های معتبر، و گرفتن token استفاده خواهیم کرد.

حال، برنامه را اجرا کنید و برای آزمون ورود به سیستم، postman را باز کنید. در header، content type  را به ” application/json ” تغییر دهید.

.Net Core و JWT

نام‌کاربری و رمزعبور معتبر (فرمت JSON) را در بدنه اضافه کنید.

{  
   "UserName":"johncitizen",  
   "Password": "abc@123"  
}   
 

.Net Core و JWT

اگر این جزئیات را ارسال کنید، سرور یک token ارائه خواهد داد.

بنابراین، با این کار، یک سرور ارائه‌دهنده‌ی token را پیکربندی کرده‌ایم.

اگرچه یک token داریم، اما برنامه برای مدیریت و تفسیر token تجهیز نشده‌است.

نیاز است این توانایی را اضافه کنیم، تا token مربوط به درخواست سرویس‌گیرنده بتواند مورد فهم سرور واقع شود.

این کد را در متد ” ConfigureServices “، در کلاس ” startup.cs ” اضافه کنید.

public void ConfigureServices(IServiceCollection services)  
       {  
           services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)  
           .AddJwtBearer(options =>  
           {  
               options.TokenValidationParameters = new TokenValidationParameters  
               {  
                   ValidateIssuer = true,  
                   ValidateAudience = true,  
                   ValidateLifetime = true,  
                   ValidateIssuerSigningKey = true,  
  
                   ValidIssuer = "http://localhost:2000",  
                   ValidAudience = "http://localhost:2000",  
                   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("KeyForSignInSecret@1234"))  
               };  
           });  
  
           services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
       }  

اگر متوجه شده باشید، برنامه را از احراز هویت JWT و پرسش جهت اعتبارسنجی محتواهای token آگاه می‌کنیم؛

یعنی Issuer، Audience، Lifetime و امضای دیجیتالی.

همچنین توجه کنید که نیاز است ValidIssuer، ValidAudience، و IssuerSigningKey را درست همانطور که در زمان نوشتن تولید token انجام دادیم، تامین کنیم.

دلیل این امر این است که از حالت فشرده خارج‌کردن و تولید token باید منطق مشترکی داشته باشند.

این کار، بخش دوم درخواست، یعنی ارسال یک token به سرور منبع، احراز هویت و بازگشت به منبع در صورتیکه token معتبر باشد، را تکمیل می‌کند.

.Net Core و JWT

برای آزمودن این بخش، ابتدا token را (از طریق URL مربوط به ورود به سیستم و اعتبارنامه‌های کاربر) در postman (همانطور که پیش‌تر انجام دادیم) تولید کرده، token را کپی می‌کنیم.

یک سربرگ/نمونه‌ی دیگر postman را باز کرده، URL مربوط به مقادیر را قرار می‌دهیم، نوع ” Bearer Token ” را انتخاب کرده و token تولید شده‌ی فوق را در اینجا کپی می‌کنیم.

درخواست را ارسال کرده و باید پاسخی دریافت کنید.

.Net Core و JWT

کدنویسی به کامتان!

زهره سلطانیان

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.