Skip to main content
BuildingBlocks.Jwt, Keycloak token’larının dışında uygulamanın kendi ürettiği iki ayrı JWT şemasını yönetir: uzun ömürlü Backoffice oturum token’ı ve kısa ömürlü OTPChallenge token’ı. Tek AddJwt(...) çağrısı iki JwtBearer şeması kurar; JwtTokenValidator token doğrulama/claim okuma sağlar.

Token sarmalayıcılar

TipÜyelerAmaç
JwtAccessTokenstring AccessToken, DateTime ExpiresAt, long ExpiresInSeconds (computed)Access token + son kullanma
JwtRefreshTokenbenzer yapıRefresh token taşıyıcısı

JwtTokenValidator

Simetrik (SymmetricSecurityKey, HMAC) veya OIDC (OpenIdConnectConfiguration) anahtarla token doğrular.
MetotİmzaAmaç
ctorJwtTokenValidator(string secretKey, bool validateLifetime = true, string? issuer = null, string? audience = null, OpenIdConnectConfiguration? openIdConfig = null)Doğrulayıcıyı yapılandırır
ValidateTokenbool ValidateToken(string jwt)İmza + ömür doğrular
GetClaimstring? GetClaim(string jwt, string claimType)Tek claim okur
GetClaimsIEnumerable<Claim> GetClaims(string jwt)Tüm claim’leri okur
GetPayloadJwtPayload? GetPayload(string jwt)Payload’ı parse eder
GetPayloadAs<T>T? GetPayloadAs<T>(string jwt) where T : classPayload’ı tipe deserialize eder
issuer/audience parametreleri ; ile ayrılmış çoklu değer alabilir — bu durumda ValidIssuers/ValidAudiences listesi olarak değerlendirilir. ClockSkew 60 saniyedir.

Yapılandırma — JwtOptions

Jwt bölümüne bind edilir. İki alt bölüm, ikisi de JwtBase’den türeyen tiplerde:
public class JwtOptions
{
    public BackofficeOptions Backoffice { get; set; }      // : JwtBase
    public OTPChallengeOptions OTPChallenge { get; set; }  // : JwtBase
}

JwtBase

ÜyeTipAçıklama
SecretstringHMAC imzalama anahtarı
ValidAudiencestringBeklenen audience
ValidIssuerstringBeklenen issuer
ExpiresdoubleToken ömrü (dakika)
ClockSkewintEk tolerans (saniye)

AuthenticationSchemeTypes

SabitDeğerKullanım
BackofficeAuthenticationScheme"Bearer"Uzun ömürlü backoffice oturumu
OTPChallengeAuthenticationScheme"OTPChallenge"OTP doğrulama state’i taşıyan kısa ömürlü token

DI kaydı — AddJwt

public static IServiceCollection AddJwt(this IServiceCollection services, IConfiguration configuration)
{
    services.Configure<JwtOptions>(o => configuration.GetSection("Jwt").Bind(o));
    services.Configure<RefreshTokenOptions>(o => configuration.GetSection("RefreshToken:Backoffice").Bind(o));

    // İki şema için named JwtBearerOptions yapılandırması
    services.ConfigureOptions<ConfigureBackofficeJwtOptions>();
    services.ConfigureOptions<ConfigureOTPChallengeJwtOptions>();
    services.AddHttpContextAccessor();

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme             = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(AuthenticationSchemeTypes.BackofficeAuthenticationScheme, _ => { })
    .AddJwtBearer(AuthenticationSchemeTypes.OTPChallengeAuthenticationScheme, _ => { });

    return services;
}
{
  "Jwt": {
    "Backoffice": {
      "Secret": "<min-32-char>",
      "ValidAudience": "diyanet-api",
      "ValidIssuer": "diyanet",
      "Expires": 60,
      "ClockSkew": 60
    },
    "OTPChallenge": {
      "Secret": "<min-64-char>",
      "ValidAudience": "diyanet-api",
      "ValidIssuer": "diyanet",
      "Expires": 5,
      "ClockSkew": 30
    }
  }
}
Secret’lar .env üzerinden gelir: JWT_BACKOFFICE_SECRET (min 32 karakter), JWT_OTP_SECRET (min 64 karakter). OTPChallenge token’ları kasten kısa ömürlüdür (Expires: 5) — yalnızca OTP doğrulama akışı süresince geçerlidir.

Kullanım

// Token doğrulama
var validator = new JwtTokenValidator(secret, validateLifetime: true, issuer: "diyanet", audience: "diyanet-api");
if (!validator.ValidateToken(token)) return Unauthorized();
var sub = validator.GetClaim(token, "sub");

// Endpoint koruma — Backoffice
[Authorize(AuthenticationSchemes = AuthenticationSchemeTypes.BackofficeAuthenticationScheme)]
[HttpGet("api/admin/reports")]
public async Task<IActionResult> GetReports()
    => Ok(await _mediator.Send(new GetReportsQuery()));

// Endpoint koruma — OTPChallenge (sadece OTP doğrulama adımı)
[Authorize(AuthenticationSchemes = AuthenticationSchemeTypes.OTPChallengeAuthenticationScheme)]
[HttpPost("api/admin/auth/verify-otp")]
public async Task<IActionResult> VerifyOtp([FromBody] VerifyOtpRequest req)
    => Ok(await _mediator.Send(new VerifyOtpCommand(req.Code)));

İlgili

OTP

OTPChallenge akışını besleyen kod üretimi/doğrulaması.

Keycloak

SSO realm token’ları (custom JWT’den ayrı şemalar).

Authentication

Şema seçimi ve oturum yönetimi genel bakışı.

Staff login

Backoffice + OTP login akışı baştan sona.