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:
- Her token isteği için yeni bir DPoP kanıt JWT'si üretir
DPoP-Noncesunucu doğrulama isteklerini işler ve şeffaf bir şekilde yeniden dener- Nonce'u sonraki istekler için saklar
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:
- DPoP kanıt JWT'lerini doğrular (imza, talepler, tazelik)
- Token'ları istemcinin JWK parmak izine bağlar
- DPoP'a bağlı token'lar için
token_type: DPoPdöndürür - Geçersiz veya eksik kanıtlara sahip istekleri reddeder (400
invalid_dpop_proofdöndürür) - Kaynak isteklerinde
athtalebini (erişim token'ı karması) doğrular
// 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.
