
A implementação da Delphi do JWT (JSON Web Token) e o conjunto de especificação JOSE (JSON Object Signating and Criptografia). Esta biblioteca suporta as serializações compactas do JWS (JWE Support estão planejadas) com vários algoritmos Jose.

Antes do Delphi 10 Seattle, o algoritmo HMAC-SHA usa o OpenSSL através da Biblioteca Indy; portanto, para gerar o token, você deve ter as DLLs OpenSSL no sistema de servidores.
Em Delphi 10 Seattle ou versões mais recentes do Delphi, o algoritmo HMAC também está no sistema.
O algoritmo HMAC-RSA (ECDSA) usa necessariamente o OpenSSL, portanto, se você planeja usar esses algoritmos para assinar seu token, precisará baixar e implantar OpenSSL (no servidor).
Lembre-se de que o cliente não precisa gerar ou verificar o token (usando SHA ou RSA); portanto, no lado do cliente, não há necessidade das DLLs OpenSSL.
Se você precisar da biblioteca OpenSSL no servidor, você pode baixar o pacote diretamente na página do projeto Github do Indy (lembre -se de sempre atualizar para a versão mais recente e combinar o bitness do aplicativo)
Jose é um padrão que fornece uma abordagem geral para a assinatura e criptografia de qualquer conteúdo. José consiste em vários RFC:
| Algoritmos | Suportado |
|---|---|
exp | ✔️ |
iat | ✔️ |
nbf | ✔️ |
aud | ✔️ |
iss | ✔️ |
jti | ✔️ |
typ | ✔️ |
TJOSEProducer e TJOSEProducerBuilder (também conhecido como TJOSEProcess ) para construir um novo token compacto com muitas opções TJOSEConsumer e TJOSEConsumerBuilder para validar o token com uma granularidade fina| Algoritmos | Suportado |
|---|---|
None | ✔️ Não use! ? |
HS256 | ✔️ |
HS384 | ✔️ |
HS512 | ✔️ |
RS256 | ✔️ Atualizado! |
RS384 | ✔️ Atualizado! |
RS512 | ✔️ Atualizado! |
ES256 | ✔️ Novo! ? |
ES384 | ✔️ Novo! ? |
ES512 | ✔️ Novo! ? |
ES256K | ✔️ Novo! ? |
None algoritmoEsta biblioteca foi testada com Delphi 12 Atenas , Delphi 11 Alexandria , Delphi 10.4 Sydney , Delphi 10.3 Rio , Delphi 10.2 Tóquio Mas, com algum trabalho, deve compilar com o DXE6 e superior , mas não tentei ou testei, se você for bem -sucedido, ficarei feliz para criar um ramo de seu trabalho!
Esta biblioteca não tem dependências de bibliotecas/unidades externas.
Unidades Delphi usadas:
Basta adicionar o caminho da origem "Origem/Common" e a fonte/Jose "ao seu caminho do projeto Delphi e ... você está pronto!
Usando o comando boss install :
$ boss install github.com/paolo-rossi/delphi-jose-jwt Para criar um token, basta criar uma instância da classe TJWT e definir as propriedades (reivindicações).
A maneira mais fácil de construir um token JWT (representação compacta) é usar a interface IJOSEProducer :
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 ; Outra maneira de serializar, desaperializar, verificar um token é usar a classe de utilitário TJOSE :
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 ; Usando as classes TJWT , TJWS e TJWK , você tem mais controle sobre a criação do token compacto final.
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 ;
Desmarcar e verificar tokens é simples.
Você tem que passar a chave e o formato compacto de token para a função de classe TJOSE.Verify
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 ; Usando a nova classe TJOSEConsumer , é muito fácil validar as reivindicações do token. O objeto TJOSEConsumer é construído com a classe utilitária TJOSEConsumerBuilder usando a interface fluente.
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 ;