
Delphi -Implementierung von JWT (JSON Web Token) und der Spezifikationssuite von JOSE (JSON -Objekt signieren und Verschlüsselung). Diese Bibliothek unterstützt die JWS (JWE Support Is Planned) Kompaktserialisierungen mit mehreren JOSE -Algorithmen.

Vor Delphi 10 Seattle verwendet der HMAC-Sha-Algorithmus OpenSL durch die Indy-Bibliothek. Um das Token zu generieren, sollten Sie die OpenSSL-DLLs in Ihrem Serversystem haben.
In Delphi 10 Seattle oder neuere Delphi -Versionen befindet sich der HMAC -Algorithmus ebenfalls im System.
Der HMAC-RSA (ECDSA) -Algorithmus verwendet notwendigerweise OpenSSL. Wenn Sie diese Algorithmen verwenden, müssen Sie OpenSSL (auf dem Server) herunterladen und bereitstellen.
Bitte beachten Sie, dass der Kunde das Token (mit SHA oder RSA) nicht generieren oder überprüfen muss. Auf der Client-Seite sind die OpenSSL-DLLs nicht erforderlich.
Wenn Sie die OpenSSL -Bibliothek auf dem Server benötigen, können Sie das Paket direkt auf die GitHub -Projektseite des Indy herunterladen (denken Sie daran, immer auf die neueste Version zu aktualisieren und die Bitness Ihrer Anwendung zu entsprechen).
Jose ist ein Standard, der einen allgemeinen Ansatz für die Unterzeichnung und Verschlüsselung von Inhalten bietet. Jose besteht aus mehreren RFC:
| Algorithmen | Unterstützt |
|---|---|
exp | ✔️ |
iat | ✔️ |
nbf | ✔️ |
aud | ✔️ |
iss | ✔️ |
jti | ✔️ |
typ | ✔️ |
TJOSEProducer und TJOSEProducerBuilder (Alias TJOSEProcess ) Klassen, um ein neues kompaktes Token mit vielen Optionen zu erstellen TJOSEConsumer und TJOSEConsumerBuilder -Klassen, um Token mit einer feinen Körnung zu validieren| Algorithmen | Unterstützt |
|---|---|
None | ✔️ Verwenden Sie es nicht! ? |
HS256 | ✔️ |
HS384 | ✔️ |
HS512 | ✔️ |
RS256 | ✔️ Aktualisiert! |
RS384 | ✔️ Aktualisiert! |
RS512 | ✔️ Aktualisiert! |
ES256 | ✔️ Neu! ? |
ES384 | ✔️ Neu! ? |
ES512 | ✔️ Neu! ? |
ES256K | ✔️ Neu! ? |
None Algorithmus beeinflusstDiese Bibliothek wurde mit Delphi 12 Athens , Delphi 11 Alexandria , Delphi 10.4 Sydney , Delphi 10.3 Rio , Delphi 10.2 Tokio getestet. Mit einigen Arbeiten sollte sie jedoch mit DXE6 und höher kompilieren, aber ich habe dies nicht ausprobiert oder getestet, wenn Sie in dieser Aufgabe erfolgreich sind, erstellen ich gerne einen Zweig Ihrer Arbeit!
Diese Bibliothek hat keine Abhängigkeiten von externen Bibliotheken/Einheiten.
Verwendete Delphi -Einheiten:
Fügen Sie einfach den Quellpfad "Quelle/Common" und Quelle/Jose "Ihrem Delphi -Projektpfad hinzu und ... Sie können loslegen!
Verwenden des Befehls boss install :
$ boss install github.com/paolo-rossi/delphi-jose-jwt Um ein Token zu erstellen, erstellen Sie einfach eine Instanz der TJWT -Klasse und setzen Sie die Eigenschaften (Ansprüche).
Der einfachste Weg, um ein JWT -Token (Kompaktdarstellung) zu erstellen, besteht darin, die IJOSEProducer -Schnittstelle zu verwenden:
uses
JOSE.Producer;
var
LResult: string;
begin
LResult := TJOSEProcess.New
.SetIssuer( ' Delphi JOSE Library ' )
.SetIssuedAt(Now)
.SetExpiration(Now + 1 )
.SetAlgorithm(LAlg)
.SetKey(TJOSEAlgorithmId.HS256)
.Build
.GetCompactToken
;
memoCompact.Lines.Add(LResult);
end ; Eine andere Möglichkeit, ein Token zu serialisieren, zu deerialisieren, zu verifizieren, besteht darin, die TJOSE -Dienstprogrammklasse zu verwenden:
uses
JOSE.Core.JWT,
JOSE.Core.Builder;
var
LToken: TJWT;
LCompactToken: string;
begin
LToken := TJWT.Create;
try
// Token claims
LToken.Claims.Issuer := ' WiRL REST Library ' ;
LToken.Claims.Subject := ' Paolo Rossi ' ;
LToken.Claims.Expiration := Now + 1 ;
// Signing and Compact format creation
LCompactToken := TJOSE.SHA256CompactToken( ' my_very_long_and_safe_secret_key ' , LToken);
mmoCompact.Lines.Add(LCompactToken);
finally
LToken.Free;
end ; Mit den TJWT , TJWS und TJWK -Klassen haben Sie mehr Kontrolle über die Erstellung des endgültigen kompakten Tokens.
var
LToken: TJWT;
LSigner: TJWS;
LKey: TJWK;
LAlg: TJOSEAlgorithmId;
begin
LToken := TJWT.Create;
try
// Set your claims
LToken.Claims.Subject := ' Paolo Rossi ' ;
LToken.Claims.Issuer := ' Delphi JOSE Library ' ;
LToken.Claims.IssuedAt := Now;
LToken.Claims.Expiration := Now + 1 ;
// Choose the signing algorithm
case cbbAlgorithm.ItemIndex of
0 : LAlg := TJOSEAlgorithmId.HS256;
1 : LAlg := TJOSEAlgorithmId.HS384;
2 : LAlg := TJOSEAlgorithmId.HS512;
else LAlg := TJOSEAlgorithmId.HS256;
end ;
// Create your key from any text or TBytes
LKey := TJWK.Create(edtSecret.Text);
try
// Create the signer
LSigner := TJWS.Create(LToken);
try
// With this option you can have keys < algorithm length
LSigner.SkipKeyValidation := True;
// Sign the token!
LSigner.Sign(LKey, LAlg);
memoCompact.Lines.Add( ' Header: ' + LSigner.Header);
memoCompact.Lines.Add( ' Payload: ' + LSigner.Payload);
memoCompact.Lines.Add( ' Signature: ' + LSigner.Signature);
memoCompact.Lines.Add( ' Compact Token: ' + LSigner.CompactToken);
finally
LSigner.Free;
end ;
finally
LKey.Free;
end ;
finally
LToken.Free;
end ;
Das Auspacken und Überprüfen von Token ist einfach.
Sie müssen den Schlüssel und das Token -Kompaktformat an die TJOSE.Verify -Klassenfunktion übergeben
var
LKey: TJWK;
LToken: TJWT;
begin
// Create the key from a text or TBytes
LKey := TJWK.Create( ' my_very_long_and_safe_secret_key ' );
// Unpack and verify the token!
LToken := TJOSE.Verify(LKey, FCompactToken);
if Assigned(LToken) then
begin
try
if LToken.Verified then
mmoJSON.Lines.Add( ' Token signature is verified ' )
else
mmoJSON.Lines.Add( ' Token signature is not verified ' )
finally
LToken.Free;
end ;
end ;
end ; Mit der neuen Klasse TJOSEConsumer ist es sehr einfach, die Ansprüche des Tokens zu validieren. Das TJOSEConsumer -Objekt wird mit der TJOSEConsumerBuilder -Dienstprogrammklasse mit der fließenden Schnittstelle erstellt.
var
LConsumer: IJOSEConsumer;
begin
LConsumer := TJOSEConsumerBuilder.NewConsumer
.SetClaimsClass(TJWTClaims)
// JWS-related validation
.SetVerificationKey(edtConsumerSecret.Text)
.SetSkipVerificationKeyValidation
.SetDisableRequireSignature
// string-based claims validation
.SetExpectedSubject( ' paolo-rossi ' )
.SetExpectedAudience(True, [ ' Paolo ' ])
// Time-related claims validation
.SetRequireIssuedAt
.SetRequireExpirationTime
.SetEvaluationTime(IncSecond(FNow, 26 ))
.SetAllowedClockSkew( 20 , TJOSETimeUnit.Seconds)
.SetMaxFutureValidity( 20 , TJOSETimeUnit.Minutes)
// Build the consumer object
.Build();
try
// Process the token with your rules!
LConsumer.Process(Compact);
except
// (optionally) log the errors
on E: Exception do
memoLog.Lines.Add(E.Message);
end ;