আমি এই প্রশ্নের উত্তর দিয়েছি: 4 বছর আগে এইচএমএসি ব্যবহার করে একটি এএসপি.নেট ওয়েব এপিআই কীভাবে সুরক্ষিত করা যায় ।
এখন, সুরক্ষার পরিবর্তে প্রচুর জিনিসগুলি বিশেষত জেডাব্লুটি জনপ্রিয় হয়ে উঠছে। এখানে, আমি কীভাবে সহজ এবং মৌলিক উপায়ে JWT ব্যবহার করতে পারি তা বোঝানোর চেষ্টা করব, সুতরাং আমরা ওউইএন, ওউথ 2, এএসপি.নেট পরিচয় জঙ্গল থেকে হারিয়ে যাব না ... :)।
আপনি যদি জেডাব্লুটি টোকেন না জানেন তবে আপনার এখানে কিছুটা নজর দেওয়া দরকার:
https://tools.ietf.org/html/rfc7519
মূলত, একটি JWT টোকেন দেখতে:
<base64-encoded header>.<base64-encoded claims>.<base64-encoded signature>
উদাহরণ:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImN1b25nIiwibmJmIjoxNDc3NTY1NzI0LCJleHAiOjE0Nzc1NjY5MjQsImlhdCI6MTQ3NzU2NTcyNH0.6MzD1VwA5AcOcajkFyKhLYybr3h13iZjDyHm9zysDFQ
একটি JWT টোকেনের তিনটি বিভাগ রয়েছে:
- শিরোনাম: JSON ফর্ম্যাট যা বেস 64 এ এনকোড করা আছে
- দাবিগুলি: JSON ফর্ম্যাট যা বেস 64 এ এনকোড করা আছে।
- স্বাক্ষর: শিরোনাম এবং দাবিগুলির ভিত্তিতে তৈরি এবং স্বাক্ষরিত করা হয়েছে যা বেস 64 এ এনকোড করা আছে।
যদি আপনি উপরের টোকেনটি দিয়ে jwt.io ওয়েবসাইটটি ব্যবহার করেন তবে আপনি টোকেনটি ডিকোড করতে পারেন এবং নীচের মত দেখতে পারেন:
প্রযুক্তিগতভাবে, জেডাব্লুটিটি স্বাক্ষর ব্যবহার করে যা শিরোনাম থেকে স্বাক্ষরিত হয় এবং শিরোনামগুলিতে উল্লিখিত সুরক্ষা অ্যালগরিদমের সাথে দাবী করে (উদাহরণস্বরূপ: এইচএমএএসএএসএসিএ 25)। সুতরাং, আপনি যদি দাবিতে কোনও সংবেদনশীল তথ্য সঞ্চয় করেন তবে জেডাব্লুটিটি এইচটিটিপিগুলির মাধ্যমে স্থানান্তরিত হওয়া দরকার।
এখন, জেডাব্লুটি প্রমাণীকরণ ব্যবহার করার জন্য, যদি আপনার কোনও লিগ্যাসি ওয়েব এপিআই সিস্টেম থাকে তবে আপনাকে সত্যই কোনও ওউইন মিডলওয়্যারের প্রয়োজন হবে না। সাধারণ ধারণাটি কীভাবে জেডাব্লুটি টোকেন সরবরাহ করবেন এবং অনুরোধ এলে কীভাবে টোকেনকে বৈধতা দেওয়া যায়। এটাই.
ডেমোতে ফিরে যান, জেডাব্লুটি টোকেনকে হালকা ওজনের রাখতে আমি কেবল সঞ্চয় করি username
এবং expiration time
জেডব্লিউটিতে। তবে এইভাবে, আরও তথ্য যুক্ত করতে আপনাকে নতুন স্থানীয় পরিচয় (অধ্যক্ষ) পুনর্নির্মাণ করতে হবে: ভূমিকা .. আপনি যদি ভূমিকা অনুমোদন করতে চান তবে। তবে, আপনি যদি জেডাব্লুটিটিতে আরও তথ্য যুক্ত করতে চান তবে এটি আপনার উপর নির্ভর করে: এটি খুব নমনীয়।
OWIN মিডলওয়্যার ব্যবহার না করে, আপনি কেবল নিয়ামকের কাছ থেকে ক্রিয়া ব্যবহার করে একটি JWT টোকেন শেষ পয়েন্ট সরবরাহ করতে পারেন:
public class TokenController : ApiController
{
// This is naive endpoint for demo, it should use Basic authentication
// to provide token or POST request
[AllowAnonymous]
public string Get(string username, string password)
{
if (CheckUser(username, password))
{
return JwtManager.GenerateToken(username);
}
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}
public bool CheckUser(string username, string password)
{
// should check in the database
return true;
}
}
এটি একটি নিষ্পাপ কর্ম; উত্পাদনে আপনার জেডাব্লুটি টোকেন সরবরাহ করতে একটি পোষ্ট অনুরোধ বা একটি বেসিক প্রমাণীকরণের শেষ পয়েন্ট ব্যবহার করা উচিত।
উপর ভিত্তি করে টোকেন জেনারেট করবেন কীভাবে username
?
System.IdentityModel.Tokens.Jwt
টোকেন তৈরি করতে আপনি মাইক্রোসফ্ট থেকে ডেকে নেওয়া নুগেট প্যাকেজ ব্যবহার করতে পারেন , অথবা আপনি চাইলে অন্য কোনও প্যাকেজও ব্যবহার করতে পারেন। ডেমো, আমি ব্যবহার HMACSHA256
সঙ্গে SymmetricKey
:
/// <summary>
/// Use the below code to generate symmetric Secret Key
/// var hmac = new HMACSHA256();
/// var key = Convert.ToBase64String(hmac.Key);
/// </summary>
private const string Secret = "db3OIsj+BXE9NZDy0t8W3TcNekrF+2d/1sFnWG4HnV8TZY30iTOdtVWJG8abWvB1GlOgJuQZdcF2Luqm/hccMw==";
public static string GenerateToken(string username, int expireMinutes = 20)
{
var symmetricKey = Convert.FromBase64String(Secret);
var tokenHandler = new JwtSecurityTokenHandler();
var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, username)
}),
Expires = now.AddMinutes(Convert.ToInt32(expireMinutes)),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(symmetricKey),
SecurityAlgorithms.HmacSha256Signature)
};
var stoken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(stoken);
return token;
}
জেডাব্লুটি টোকেন সরবরাহ করার শেষ পয়েন্টটি সম্পন্ন হয়েছে। এখন, অনুরোধ এলে কীভাবে JWT বৈধ করবেন? ডেমো আমি নির্মাণ করেছি
JwtAuthenticationAttribute
যা থেকে উত্তরাধিকারী IAuthenticationFilter
(ইন প্রমাণীকরণ ফিল্টার সম্পর্কে আরো বিস্তারিত এখানে )।
এই অ্যাট্রিবিউট দিয়ে, আপনি যে কোনও ক্রিয়াকলাপকে প্রমাণীকরণ করতে পারেন: আপনাকে কেবলমাত্র এই ক্রিয়াটির উপরে এই বৈশিষ্ট্যটি রাখতে হবে।
public class ValueController : ApiController
{
[JwtAuthentication]
public string Get()
{
return "value";
}
}
আপনি যদি নিজের ওয়েবএপিআইয়ের জন্য আগত সমস্ত অনুরোধ (কন্ট্রোলার বা কর্মের সাথে সুনির্দিষ্ট না হয়) বৈধ করতে চান তবে আপনি ওউইন মিডলওয়্যার বা ডেলিগেটহ্যান্ডারও ব্যবহার করতে পারেন
নীচে প্রমাণীকরণ ফিল্টার থেকে মূল পদ্ধতি:
private static bool ValidateToken(string token, out string username)
{
username = null;
var simplePrinciple = JwtManager.GetPrincipal(token);
var identity = simplePrinciple.Identity as ClaimsIdentity;
if (identity == null)
return false;
if (!identity.IsAuthenticated)
return false;
var usernameClaim = identity.FindFirst(ClaimTypes.Name);
username = usernameClaim?.Value;
if (string.IsNullOrEmpty(username))
return false;
// More validate to check whether username exists in system
return true;
}
protected Task<IPrincipal> AuthenticateJwtToken(string token)
{
string username;
if (ValidateToken(token, out username))
{
// based on username to get more information from database
// in order to build local identity
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username)
// Add more claims if needed: Roles, ...
};
var identity = new ClaimsIdentity(claims, "Jwt");
IPrincipal user = new ClaimsPrincipal(identity);
return Task.FromResult(user);
}
return Task.FromResult<IPrincipal>(null);
}
ওয়ার্কফ্লো হ'ল, জেডাব্লুটি লাইব্রেরি (উপরে নিউগেট প্যাকেজ) ব্যবহার করে জেডাব্লুটি টোকেনকে বৈধতা দিন এবং তারপরে ফিরে আসুন ClaimsPrincipal
। আপনি আপনার সিস্টেমে ব্যবহারকারীর উপস্থিতি আছে কিনা তা যাচাই করে আপনি চাইলে অন্যান্য কাস্টম বৈধতা যুক্ত করতে পারেন যেমন আপনি আরও বৈধতা সম্পাদন করতে পারেন। জেডাব্লুটি টোকেনকে বৈধতা দেওয়ার জন্য এবং প্রধান ফিরে পেতে কোড:
public static ClaimsPrincipal GetPrincipal(string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;
if (jwtToken == null)
return null;
var symmetricKey = Convert.FromBase64String(Secret);
var validationParameters = new TokenValidationParameters()
{
RequireExpirationTime = true,
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
};
SecurityToken securityToken;
var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
return principal;
}
catch (Exception)
{
//should write log
return null;
}
}
যদি জেডাব্লুটি টোকেনটি বৈধ হয়ে থাকে এবং অধ্যক্ষটি ফিরে আসে, আপনার উচিত নতুন স্থানীয় পরিচয় তৈরি করা এবং ভূমিকা অনুমোদনের জন্য এটিতে আরও তথ্য রাখা উচিত।
যোগ করার জন্য মনে রাখুন config.Filters.Add(new AuthorizeAttribute());
(ডিফল্ট অনুমোদন) আপনার সম্পদ কোনো বেনামী অনুরোধ প্রতিরোধ করার জন্য বিশ্বব্যাপী সুযোগ হয়েছে।
আপনি ডেমোটি পরীক্ষা করতে পোস্টম্যান ব্যবহার করতে পারেন:
অনুরোধ টোকেন (আমি উপরে বর্ণিত হিসাবে নির্বোধ, কেবলমাত্র ডেমো জন্য):
GET http://localhost:{port}/api/token?username=cuong&password=1
অনুমোদিত অনুরোধের জন্য শিরোনামে JWT টোকেন রাখুন, উদাহরণস্বরূপ:
GET http://localhost:{port}/api/value
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImN1b25nIiwibmJmIjoxNDc3NTY1MjU4LCJleHAiOjE0Nzc1NjY0NTgsImlhdCI6MTQ3NzU2NTI1OH0.dSwwufd4-gztkLpttZsZ1255oEzpWCJkayR_4yvNL1s
ডেমোটি এখানে রাখা হয়েছে: https://github.com/cuongle/WebApi.Jwt