المصادقة والتفويض في Java: Spring Security و JWT

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

المصادقة والتفويض في Java: Spring Security و JWT



تنظيم الوصول الآمن إلى الموارد هو أحد المهام الأساسية عند تطوير تطبيقات الويب بلغة Java. في هذه المقالة، سنشرح مفهومين أساسيين: المصادقة (التحقق من هوية المستخدم) والتفويض (التحقق من صلاحيات الوصول). سنستعرض أمثلة عملية باستخدام إطار العمل الشهير Spring Security وتقنية JSON Web Tokens (JWT).



1. المفاهيم الأساسية



قبل الانتقال إلى الكود، من المهم التمييز بوضوح بين المصطلحات:



  • المصادقة (Authentication) — عملية التحقق من هوية المستخدم. تتم عادةً عبر اسم المستخدم وكلمة المرور، أو القياسات الحيوية، أو الرموز.
  • التفويض (Authorization) — عملية تحديد ما يُسمح للمستخدم بفعله. على سبيل المثال، الوصول إلى نقاط نهاية معينة في API أو وظائف التطبيق.


في تطبيقات Java الحديثة، لتنفيذ هذه الآليات، يُستخدم غالبًا مزيج Spring Security + JWT. يتيح JWT تخزين معلومات المستخدم في رمز مضغوط يسهل نقله بين العميل والخادم.



2. إعداد Spring Security مع JWT



سنضيف التبعيات اللازمة في ملف pom.xml (Maven):



<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-security</artifactId></dependency><dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-api</artifactId>    <version>0.12.3</version></dependency><dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-impl</artifactId>    <version>0.12.3</version>    <scope>runtime</scope></dependency><dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-jackson</artifactId>    <version>0.12.3</version>    <scope>runtime</scope></dependency>


3. إنشاء خدمة للعمل مع JWT



سننشئ كلاس JwtService الذي سيتولى إنشاء الرموز والتحقق منها:



import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import io.jsonwebtoken.security.Keys;import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;import java.util.Date;import java.util.HashMap;import java.util.Map;

@Servicepublic class JwtService {

private final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); private final long expirationMs = 86400000; // 24 ساعة

public String generateToken(String username) { Map<String, Object> claims = new HashMap<>(); return Jwts.builder() .setClaims(claims) .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expirationMs)) .signWith(secretKey) .compact(); }

public String extractUsername(String token) { return extractAllClaims(token).getSubject(); }

private Claims extractAllClaims(String token) { return Jwts.parserBuilder() .setSigningKey(secretKey) .build() .parseClaimsJws(token) .getBody(); }

public boolean isTokenValid(String token, String username) { final String extractedUsername = extractUsername(token); return (extractedUsername.equals(username) && !isTokenExpired(token)); }

private boolean isTokenExpired(String token) { return extractAllClaims(token).getExpiration().befo

توصيات