OAuth2 dPoP Delphi

· Özellikler

OAuth 2.0 erişim token'ları, API krallığınızın anahtarlarıdır ve birisi bir tanesini çalarsa, onu her yerden kullanabilir. RFC 9449'da tanımlanan DPoP (Demonstrating Proof of Possession), bunu token'ları, onları talep eden istemciye kriptografik olarak bağlayarak çözer. Bir token ele geçirilse bile, istemcinin özel anahtarı olmadan işe yaramaz hale gelir.

sgcWebSockets 2026.4.0 sürümünden itibaren, OAuth2 istemci ve sunucu bileşenleri tam DPoP desteği içerir. Bu makale, DPoP'un ne olduğunu, nasıl çalıştığını ve Delphi uygulamanızda nasıl yapılandırılacağını açıklar.

DPoP nedir?

Standart OAuth 2.0'da bir Bearer token nakit para gibi çalışır: onu kim elinde tutuyorsa harcayabilir. Bir saldırgan token'ı ele geçirilmiş bir ağ, sızdırılmış günlükler veya kötü amaçlı bir proxy aracılığıyla ele geçirirse, korunan kaynaklarınıza tam erişime sahip olur.

DPoP, token'ları PIN'li bir kredi kartı gibi çalıştırarak bunu değiştirir. Token'ın kendisi bir genel anahtara bağlıdır ve her isteğin, karşılık gelen özel anahtarla imzalanmış bir kanıt JWT'si içermesi gerekir. Sunucu, isteği kabul etmeden önce kanıtın bağlı anahtarla eşleştiğini doğrular.

Bearer Token (geleneksel)
Token'a sahip olan herkes onu kullanabilir. Çalınan token'lar tamamen istismar edilebilir. Kimlik kanıtı gerekmez.
DPoP Token (gönderici kısıtlı)
Token bir anahtar çiftine bağlıdır. Her istek yeni bir imzalı kanıt gerektirir. Çalınan token'lar özel anahtar olmadan değersizdir.

DPoP Nasıl Çalışır

DPoP akışı, standart OAuth2 sürecine hafif bir kriptografik adım ekler:

1. Anahtar Üretimi İstemci, asimetrik bir anahtar çifti (ES256 veya RS256) üretir. Özel anahtar istemcide kalır; genel anahtar, DPoP kanıtlarına bir JWK olarak dahil edilir.

2. Token İsteği Bir erişim token'ı talep ederken, istemci imzalı bir JWT kanıtı içeren bir DPoP HTTP başlığı ekler. Kanıt; HTTP metodunu, URL'yi, zaman damgasını ve benzersiz bir tanımlayıcıyı içerir.

3. Token Bağlama Yetkilendirme sunucusu kanıt imzasını doğrular, JWK parmak izini (genel anahtarın SHA-256 karması) çıkarır ve bunu verilen token'a bağlar. Yanıt, Bearer yerine token_type: DPoP içerir.

4. Kaynak Erişimi Her API çağrısı için istemci hem token'ı hem de yeni bir DPoP kanıtı gönderir. Kanıt, kanıtı o belirli token'a bağlayan bir ath talebi (erişim token'ının SHA-256 karması) içerir.

Bir DPoP Kanıtının İçi

Bir DPoP kanıtı, üç bölümden oluşan kompakt bir JWT'dir: başlık, yük (payload) ve imza.

// Header - identifies the key and algorithm
{
  "typ": "dpop+jwt",
  "alg": "ES256",
  "jwk": {
    "kty": "EC",
    "crv": "P-256",
    "x": "cWs37kZLJMej6fpd...",
    "y": "e2bkcQGaBERgSZUb..."
  }
}
// Payload - proves freshness and binds to the request
{
  "htm": "POST",
  "htu": "https://auth.example.com/oauth/token",
  "iat": 1774950263,
  "jti": "F1AFCD1F-95F7-401B-A2F5-195A31DB1802",
  "ath": "fUHyO2r2Z3DZ53EsNr..."
}

sgcWebSockets'te DPoP Yapılandırma

Adım 1: Bir ES256 Anahtar Çifti Üretin

Bir eliptik eğri anahtar çifti üretmek için OpenSSL kullanın:

# Generate EC private key
openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
# Extract public key parameters
openssl ec -in dpop_private.pem -text -noout

JWK'yi oluşturmak için genel anahtarın X ve Y koordinatlarını Base64URL'ye dönüştürün:

{"kty":"EC","crv":"P-256","x":"cWs37kZLJMej6fpdyKaI8Gz6CE...","y":"e2bkcQGaBERgSZUbAGR-iOOM..."}

Adım 2: OAuth2 İstemcisini Yapılandırın

// Configure OAuth2 as usual
OAuth2.OAuth2Options.GrantType := auth2CodePKCE;
OAuth2.OAuth2Options.ClientId := 'your-client-id';
OAuth2.OAuth2Options.ClientSecret := 'your-client-secret';
OAuth2.AuthorizationServerOptions.AuthURL := 'https://auth.example.com/authorize';
OAuth2.AuthorizationServerOptions.TokenURL := 'https://auth.example.com/oauth/token';
// Enable DPoP
OAuth2.DPoPOptions.Enabled := True;
OAuth2.DPoPOptions.Algorithm := dpopES256;
OAuth2.DPoPOptions.PrivateKey.LoadFromFile('dpop_private.pem');
OAuth2.DPoPOptions.PublicKeyJWK := '{"kty":"EC","crv":"P-256","x":"...","y":"..."}';
// Start the OAuth2 flow - DPoP headers are added automatically
OAuth2.Start;

Hepsi bu kadar. Bileşen otomatik olarak:

Adım 3: API Çağrıları için DPoP Kanıtlarını Kullanın

DPoP'a bağlı bir erişim token'ı edindikten sonra, her API isteği için bir kanıt üretin:

var
  vProof: String;
begin
  // Generate a DPoP proof for the API call
  vProof := OAuth2.GetDPoPProof(
    'GET',
    'https://api.example.com/userinfo',
    OAuth2.AccessToken
  );
  // Include both headers in your HTTP request:
  //   Authorization: DPoP <access_token>
  //   DPoP: <proof_jwt>
  HTTPClient.Request.CustomHeaders.AddValue('Authorization',
    'DPoP ' + OAuth2.AccessToken);
  HTTPClient.Request.CustomHeaders.AddValue('DPoP', vProof);
  HTTPClient.Get('https://api.example.com/userinfo');
end;

Desteklenen Sağlayıcılar

DPoP, başlıca OAuth2 sağlayıcıları tarafından zaten desteklenmektedir:

Auth0 DPoP'u uygulama ayarlarında etkinleştirin. Nonce desteği gerektirir (otomatik olarak işlenir).
Okta DPoP'u yetkilendirme sunucusu erişim politikalarında yapılandırın. 2024'ten beri genel kullanıma açık.
Microsoft Entra ID Gizli istemciler için DPoP'u destekler.
Ping Identity PingOne ve PingFederate'te tam DPoP desteği.

Sunucu Tarafı DPoP Doğrulaması

sgcWebSockets OAuth2 sunucu bileşeni de DPoP doğrulamasını destekler. OAuth2Options.DPoP etkinleştirildiğinde, sunucu otomatik olarak:

// Enable DPoP on the OAuth2 server
OAuth2Server.OAuth2Options.DPoP := True;
// Optional: custom validation via event
OAuth2Server.OnOAuth2ValidateDPoP := procedure(Sender: TObject;
  Connection: TsgcWSConnection;
  const DPoPProof, AccessToken: String;
  var IsValid: Boolean)
begin
  // Add custom checks here (e.g., verify against a key registry)
  IsValid := True;
end;

DPoP API Referansı

Özellik / Metot Açıklama
DPoPOptions.Enabled Tüm token istekleri için DPoP'u etkinleştirir.
DPoPOptions.Algorithm dpopES256 (önerilen) veya dpopRS256.
DPoPOptions.PrivateKey DPoP kanıtlarını imzalamak için PEM kodlu özel anahtar.
DPoPOptions.PublicKeyJWK Genel anahtarın JSON Web Key temsili.
GetDPoPProof() Belirli bir HTTP metodu, URL ve erişim token'ı için bir DPoP kanıt JWT'si üretir.
GetDPoPJWKThumbprint() Genel anahtarın RFC 7638 SHA-256 parmak izini döndürür.
DPoPNonce Sunucudan gelen geçerli DPoP-Nonce değeri (salt okunur).

Token Güvenliğinizi Yükseltin

DPoP, PKCE'den bu yana OAuth 2.0 token güvenliğindeki en önemli iyileştirmedir. Minimum kod değişikliğiyle token hırsızlığı saldırılarının tüm sınıfını ortadan kaldırır: yalnızca DPoPOptions.Enabled := True ayarlayın, anahtarlarınızı sağlayın ve gerisini sgcWebSockets bileşeni halletsin.

DPoP desteği, hem Delphi (DXE6'dan D13'e) hem de .NET (.NET Framework 2.0'dan .NET 9'a) için sgcWebSockets 2026.4.0 sürümünde mevcuttur. En son sürümü esegece.com adresinden indirin.