C# İle Jwt Kullanarak Güvenli Kimlik Doğrulama Servisi Nasıl Yapılır?

C# İle Jwt Kullanarak Güvenli Kimlik Doğrulama Servisi Nasıl Yapılır?
C# İle Jwt Kullanarak Güvenli Kimlik Doğrulama Servisi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. Bu eğitimde .NET 9.0 veya üzeri sürümler hedeflenmiştir.

  • SDK: .NET 9.0 SDK veya daha güncel bir sürüm.
  • IDE: Visual Studio 2022 veya JetBrains Rider.
  • Bilgi: Temel ASP.NET Core Middleware ve Dependency Injection (Bağımlılık Enjeksiyonu) bilgisi.

Projenizi oluşturmak için terminal üzerinden şu komutu çalıştırabilirsiniz:

dotnet new webapi -n GuvenliAuthServisi
cd GuvenliAuthServisi
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

JWT Yapılandırması ve Ayarlar

JWT'nin güvenli çalışması için anahtar yönetimi kritiktir. appsettings.json dosyasında token oluştururken kullanılacak gizli anahtarı (Secret Key) ve yayıncı bilgilerini tanımlamanız gerekir.

{
  "Jwt": {
    "Key": "BuCokGizliVeUzunBirAnahtarDegeri_2026_Guvenlik",
    "Issuer": "myapp.com",
    "Audience": "myapp.com"
  }
}

Bu değerler, token'ın imzasını doğrulamak için kullanılır. Not: Üretim ortamında bu anahtarı asla kod içinde tutmayın, Azure Key Vault veya Environment Variables (Ortam Değişkenleri) kullanın.

Token Üretim Servisinin Hazırlanması

Token oluşturma işlemi, kullanıcının kimlik bilgileri doğrulandıktan sonra gerçekleştirilir. Aşağıdaki servis, kullanıcı bilgilerini alıp imzalı bir JWT oluşturur.

public string GenerateToken(User user)
{
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    var claims = new[] {
        new Claim(JwtRegisteredClaimNames.Sub, user.Username),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
    };

    var token = new JwtSecurityToken(
        issuer: _configuration["Jwt:Issuer"],
        audience: _configuration["Jwt:Audience"],
        claims: claims,
        expires: DateTime.Now.AddMinutes(30),
        signingCredentials: credentials);

    return new JwtSecurityTokenHandler().WriteToken(token);
}

Bu servis, SymmetricSecurityKey kullanarak token'ı imzalar ve 30 dakika geçerlilik süresi atar. Claim yapısı, kullanıcıya dair kimlik bilgilerini taşımak için kullanılır.

Kimlik Doğrulama Middleware'inin Entegrasyonu

ASP.NET Core'un kimlik doğrulama sistemini Program.cs içerisinde yapılandırmanız gerekir. Bu adım, API'nizin gelen isteklerdeki JWT'yi otomatik olarak kontrol etmesini sağlar.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new TokenValidationParameters {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
    });

builder.Services.AddAuthorization();

Bu yapılandırma, gelen her istekte "Authorization: Bearer [token]" başlığını kontrol eder. Eğer token geçersizse veya süresi dolmuşsa, sistem otomatik olarak 401 Unauthorized hatası döner.

Güvenli Kimlik Doğrulama Yöntemlerinin Karşılaştırılması

Yöntem Avantajı Dezavantajı
JWT Stateless, ölçeklenebilir İptal etmesi zordur
Session Sunucu tarafında kontrol Bellek kullanımı yüksek
OAuth2 Üçüncü taraf entegrasyonu Karmaşık kurulum

Controller Üzerinde Yetkilendirme Kullanımı

Servisleriniz hazır olduktan sonra, belirli endpoint'leri korumak için [Authorize] özniteliğini (attribute) kullanabilirsiniz. Bu, sadece geçerli bir JWT'ye sahip kullanıcıların ilgili metoda erişebilmesini sağlar.

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ProtectedController : ControllerBase
{
    [HttpGet]
    public IActionResult GetSecretData()
    {
        return Ok("Bu veri sadece giriş yapmış kullanıcılara özeldir.");
    }
}

Bu örnekte, [Authorize] özniteliği, metodun çalışması için geçerli bir token zorunluluğu getirir. Eğer token yoksa veya imzası hatalıysa, kullanıcı 401 hatası alır.

Kritik Güvenlik Uyarısı: JWT içerisine asla parola, TC kimlik numarası veya hassas kişisel veriler eklemeyin. JWT içeriği (payload) Base64 ile kodlanır ve herkes tarafından okunabilir. Sadece "Claim" adı verilen kimlik tanımlayıcılarını kullanın.

Sıkça Sorulan Sorular

JWT süresi dolduğunda ne yapmalıyım?

Kullanıcı deneyimini bozmamak için "Refresh Token" (Yenileme Jetonu) mekanizması kurmalısınız. Kısa süreli Access Token dolduğunda, Refresh Token kullanarak yeni bir Access Token alabilirsiniz.

Token'ı nerede saklamalıyım?

Web tarayıcılarında LocalStorage XSS saldırılarına açıktır. Mümkünse "HttpOnly" ve "Secure" bayraklarına sahip çerezler (cookies) kullanmak daha güvenlidir.

JWT iptal edilebilir mi?

JWT'ler doğası gereği stateless olduğu için süresi dolmadan iptal edilemezler. İptal mekanizması gerekiyorsa, "Blacklist" (kara liste) mantığıyla Redis üzerinde geçersiz kılınan token ID'lerini tutabilirsiniz.

HTTPS zorunlu mu?

Evet, JWT'nin ağ üzerinden çalınmasını önlemek için HTTPS kullanımı kesinlikle zorunludur. Aksi takdirde token'lar "Man-in-the-middle" saldırılarıyla ele geçirilebilir.

Birden fazla rolü nasıl yönetirim?

JWT içerisine ClaimTypes.Role tipinde claim'ler ekleyerek, [Authorize(Roles = "Admin")] gibi rol tabanlı yetkilendirme yapabilirsiniz.

Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce mutlaka güvenlik denetimlerinden geçirin, giriş verilerini doğrulayın (validation) ve şifreleme işlemlerinde güncel kütüphaneleri tercih edin.

JWT Uygulamalarında Performans Optimizasyonu

JWT tabanlı sistemlerde performans, özellikle yüksek trafikli API'lerde kritik bir rol oynar. Token'ın her istekte doğrulanması işlemci üzerinde bir yük oluşturur. Performansı optimize etmek için şu stratejileri izleyebilirsiniz:

  • Token Boyutunu Küçük Tutun: JWT içerisine gereksiz claim'ler eklemek, her HTTP isteğinin boyutunu artırır. Sadece kimlik doğrulama için gerekli olan minimum veriyi taşıyın.
  • Asimetrik Şifreleme Kullanın: Token doğrulama süreçlerinde RS256 gibi asimetrik algoritmalar kullanarak, özel anahtarın (private key) sadece token üreten serviste kalmasını sağlayın.
  • Önbellekleme (Caching): Sık erişilen kullanıcı izinlerini veya token doğrulama sonuçlarını Redis gibi bir dağıtık önbellek sisteminde tutarak veritabanı sorgularını azaltın.

JWT Hata Ayıklama ve İzleme Stratejileri

Geliştirme sürecinde token hatalarını tespit etmek bazen karmaşık olabilir. 401 Unauthorized hatalarının kaynağını hızlıca bulmak için ASP.NET Core'un yerleşik loglama mekanizmasını yapılandırmanız gerekir.

Özel Hata İşleme Middleware'i

Standart hata mesajları yerine, istemciye daha açıklayıcı bilgiler dönmek için özel bir middleware yazabilirsiniz. Bu, özellikle token süresi dolduğunda veya imza hatası oluştuğunda hata ayıklamayı kolaylaştırır.

public class JwtExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public JwtExceptionMiddleware(RequestDelegate next) => _next = next;

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (SecurityTokenExpiredException)
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            await context.Response.WriteAsJsonAsync(new { message = "Token süresi doldu." });
        }
        catch (Exception ex)
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await context.Response.WriteAsJsonAsync(new { message = "Beklenmeyen bir hata oluştu." });
        }
    }
}

Token İçeriğini İnceleme

Geliştirme aşamasında oluşturulan token'ın içeriğini doğrulamak için jwt.io gibi araçları kullanabilir veya uygulama içerisinde bir servis yazarak token'ın claim'lerini loglayabilirsiniz. Ancak, üretim ortamında asla hassas verileri loglara yazdırmayın.

Hata Kodu Olası Neden Çözüm
IDX10501 İmza doğrulaması başarısız Secret Key değerini ve algoritmayı kontrol edin.
IDX10223 Token süresi dolmuş Token süresini (Expires) veya saat senkronizasyonunu kontrol edin.

Bu hata ayıklama yöntemleri, uygulamanızın canlıya alınmadan önce daha kararlı çalışmasını sağlar ve üretim ortamında oluşabilecek "kullanıcı giriş yapamıyor" şikayetlerini minimize eder.

Sonuç

C# ile JWT tabanlı kimlik doğrulama servisi oluşturmak, uygulamanızın güvenliğini profesyonel bir seviyeye taşımanızı sağlar. Bu makalede, token üretiminden middleware entegrasyonuna kadar süreci adım adım inceledik. Bir sonraki adım olarak, "Refresh Token" mekanizmasını projenize dahil ederek kullanıcı oturum yönetiminizi daha dayanıklı hale getirebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Kerem Tekin

Teknik rehberler ve dijital araçların verimli kullanımı konusunda uzmanlaşmış bir editörüm. Karmaşık teknolojik süreçleri, herkesin kolayca uygulayabileceği rehberlere dönüştürerek zaman tasarrufu sağlamayı hedefliyorum.

Yorumlar (0)

Yorum Yaz