PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WEBDEV 2024 → Authentification JWT
Authentification JWT
Débuté par roumegou, 11 mar. 2022 15:01 - 9 réponses
Posté le 11 mars 2022 - 15:01
Bonjour

Nous allons devoir faire une authentification de type JWT sur un
webservice.
Avant d'intégrer une library php, C ou autre, existe-t-il un moyen de
le faire en wlangage natif

et si oui avez vous des exemples de codes ?
Merci

--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Posté le 11 mars 2022 - 15:57
Roumegou a présenté l'énoncé suivant :
Bonjour

Nous allons devoir faire une authentification de type JWT sur un webservice.
Avant d'intégrer une library php, C ou autre, existe-t-il un moyen de le
faire en wlangage natif

et si oui avez vous des exemples de codes ?
Merci


nous allons nous baser sur ça
https://gist.github.com/ysbaddaden/1063d0aa671cb3aab2f7e842cd9dcfb4

--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Posté le 11 mars 2022 - 16:58
Faisable en webdev (mon projet est en webdev PHP)

voici le cœur de ma procédure + un exemple
Procedure JWT_Base64UrlEncode(data, res is string)

i is int

WHEN EXCEPTION IN

res = Encrypt(data , "", compressNone + cryptNone, encodeBASE64)
res = Replace(res, "/", "_")
res = Replace(res, "+", "-")
res = Replace(res, CR, "")

i = Length(res)
WHILE i>0 _AND_ res[[i]]="="
i-=1
END

res = Gauche(res, i)
RESULT VRAI
DO
Erreur(ExceptionInfo(errMessage))
RENVOYER FAUX
END

Procedure JWT_Token(stMonJWT est un ST_JWT, Token est une chaîne)

WHEN EXCEPTION IN

header_, payload_, signature_ est une chaîne
Token = ""

SI PAS JWT_Base64UrlEncode(__JWT_Header, header_) ALORS RENVOYER FAUX

SI PAS JWT_Base64UrlEncode(stMonJWT.payload_json, payload_) ALORS RENVOYER FAUX

mess est une chaîne = header_ + "." + payload_
buf_cle is Buffer = HashString(HA_HMAC_SHA_256, mess, __JWT_Key)

SI PAS JWT_Base64UrlEncode(buf_cle, signature_) ALORS RENVOYER FAUX

Token = header_ + "." + payload_ + "." + signature_

RENVOYER VRAI
DO
Erreur(ExceptionInfo(errMessage))
RENVOYER FAUX
END
Membre enregistré
453 messages
Posté le 11 mars 2022 - 17:24
Bonjour,

Un peu dans la même veine, voilà ce que j'ai :

Procedure GenereJWT()

vHeaders est un Variant
vPayload est un Variant

sCléSecrète est une chaîne = "CeciEstMaCléSecrète"

vHeaders.alg = "HS256"
vHeaders.typ = "JWT"

vPayload.iss = "TestWinDev" // issuer
vPayload.iat = DateHeureVersEpoch(DateHeureSys()) // issued at
vPayload.sub = "test" // subject
vPayload.exp = DateHeureVersEpoch(DateHeureSys()) + 20*60 // expire at (maintenant + 20 minutes)

// payload spécifique à l'application
vPayload.role = "admin"

sEncodedHeaders est une chaîne = Remplace(Encode(ChaîneVersUTF8(VariantVersJSON(vHeaders,psdMinifié)),encodeBASE64URL),"=", "")
sEncodedPayload est une chaîne = Remplace(Encode(ChaîneVersUTF8(VariantVersJSON(vPayload,psdMinifié)),encodeBASE64URL),"=", "")

// génération de la signature
sSignature est une chaîne = Remplace(Encode(HashChaîne(HA_HMAC_SHA_256,sEncodedHeaders + "." + sEncodedPayload,ChaîneVersUTF8(sCléSecrète)),encodeBASE64URL),"=","")

RENVOYER sEncodedHeaders + "." + sEncodedPayload + "." + sSignature


Procedure VérifieJWT(sJWT est une chaîne) : booléen

sCléSecrète est une chaîne = "CeciEstMaCléSecrète"
jHeaders est un JSON
jPayload est un JSON

// Séparation du JWT
tableau de est un tableau de chaînes
sJWT.VersTableau(tabParties,".")

// On attend trois morceaux : headers + payload + signature
SI PAS tabParties..Occurrence = 3 ALORS
Trace("Le JWT n'est pas complet")
RENVOYER FAUX
FIN

// On vérifie l'algorithme souhaité
QUAND EXCEPTION DANS
jHeaders..FormatJSON = (Decode(tabParties[1],encodeBASE64))
FAIRE
Trace("Les entêtes ne sont pas formatées au format JSON")
RENVOYER FAUX
FIN

SI PAS jHeaders.alg..Existe ALORS
Trace("L'algorithme de signature n'est pas spécifié")
RENVOYER FAUX
FIN

// On vérifie la signature en fonction de l'algorithme décrit.
SELON jHeaders.alg
CAS "HS256":
sSignature est une chaîne = Remplace(Encode(HashChaîne(HA_HMAC_SHA_256,tabParties[1] + "." + tabParties[2],ChaîneVersUTF8(sCléSecrète)),encodeBASE64URL),"=","")
SI tabParties[3] <> sSignature ALORS
Trace("La signature ne correspond pas", tabParties[3], sSignature)
RENVOYER FAUX
FIN
AUTRE CAS
Trace("Aucun algorithme correspondant", jHeaders.alg)
RENVOYER FAUX
FIN


// On vérifie les attributs standard du payload
QUAND EXCEPTION DANS
jPayload..FormatJSON = (Decode(tabParties[1], encodeBASE64))
FAIRE
Trace("Le payload n'est pas formaté au format JSON")
RENVOYER FAUX
FIN

// Le token a-t-il expiré ?
SI jPayload.exp..Existe ALORS
SI DateHeureVersEpoch(DateHeureSys()) > jPayload.exp ALORS
Trace("Le JWT a expiré", EpochVersDateHeure(jPayload.exp))
RENVOYER FAUX
FIN
FIN

// Insérer ici d'autres contrôles métier

RENVOYER VRAI


Attention cependant, l'algorithme HMAC-SHA-256 (ou HS256 dans les JWT) n'est qu'un seul des algorithmes que le JWT peut utiliser. C'est le seul requis par les standards, mais il y en a d'autres. Et les autres sont un peu plus fastidieux à mettre en place... ;)
Posté le 11 mars 2022 - 17:30
bchanudet a formulé la demande :
Bonjour,

Un peu dans la même veine, voilà ce que j'ai :

PROCÉDURE GenereJWT()

vHeaders est un Variant
vPayload est un Variant

sCléSecrète est une chaîne = "CeciEstMaCléSecrète"

vHeaders.alg = "HS256"
vHeaders.typ = "JWT"

vPayload.iss = "TestWinDev" // issuer
vPayload.iat = DateHeureVersEpoch(DateHeureSys()) // issued at
vPayload.sub = "test" // subject
vPayload.exp = DateHeureVersEpoch(DateHeureSys()) + 20*60 // expire at
(maintenant + 20 minutes)

// payload spécifique à l'application
vPayload.role = "admin"

sEncodedHeaders est une chaîne =
Remplace(Encode(ChaîneVersUTF8(VariantVersJSON(vHeaders,psdMinifié)),encodeBASE64URL),"=",
"")
sEncodedPayload est une chaîne =
Remplace(Encode(ChaîneVersUTF8(VariantVersJSON(vPayload,psdMinifié)),encodeBASE64URL),"=",
"")

// génération de la signature
sSignature est une chaîne =
Remplace(Encode(HashChaîne(HA_HMAC_SHA_256,sEncodedHeaders + "." +
sEncodedPayload,ChaîneVersUTF8(sCléSecrète)),encodeBASE64URL),"=","")

RENVOYER sEncodedHeaders + "." + sEncodedPayload + "." + sSignature


PROCÉDURE VérifieJWT(sJWT est une chaîne) : booléen

sCléSecrète est une chaîne = "CeciEstMaCléSecrète"
jHeaders est un JSON jPayload est un JSON

// Séparation du JWT
tabParties est un tableau de chaînes
sJWT.VersTableau(tabParties,".")

// On attend trois morceaux : headers + payload + signature
SI PAS tabParties..Occurrence = 3 ALORS Trace("Le JWT n'est pas complet")
RENVOYER Faux
FIN

// On vérifie l'algorithme souhaité
QUAND EXCEPTION DANS
jHeaders..FormatJSON = (Décode(tabParties[1],encodeBASE64))
FAIRE
Trace("Les entêtes ne sont pas formatées au format JSON")
RENVOYER Faux
FIN

SI PAS jHeaders.alg..Existe ALORS
Trace("L'algorithme de signature n'est pas spécifié")
RENVOYER Faux
FIN

// On vérifie la signature en fonction de l'algorithme décrit.
SELON jHeaders.alg
CAS "HS256": sSignature est une chaîne =
Remplace(Encode(HashChaîne(HA_HMAC_SHA_256,tabParties[1] + "." +
tabParties[2],ChaîneVersUTF8(sCléSecrète)),encodeBASE64URL),"=","")
SI tabParties[3] <> sSignature ALORS
Trace("La signature ne correspond pas", tabParties[3], sSignature)
RENVOYER Faux
FIN
AUTRE CAS
Trace("Aucun algorithme correspondant", jHeaders.alg)
RENVOYER Faux
FIN


// On vérifie les attributs standard du payload
QUAND EXCEPTION DANS jPayload..FormatJSON = (Décode(tabParties[1],
encodeBASE64))
FAIRE
Trace("Le payload n'est pas formaté au format JSON")
RENVOYER Faux
FIN

// Le token a-t-il expiré ?
SI jPayload.exp..Existe ALORS
SI DateHeureVersEpoch(DateHeureSys()) > jPayload.exp ALORS
Trace("Le JWT a expiré", EpochVersDateHeure(jPayload.exp))
RENVOYER Faux
FIN
FIN

// Insérer ici d'autres contrôles métier

RENVOYER Vrai


Attention cependant, l'algorithme HMAC-SHA-256 (ou HS256 dans les JWT) n'est
qu'un seul des algorithmes que le JWT peut utiliser. C'est le seul requis par
les standards, mais il y en a d'autres. Et les autres sont un peu plus
fastidieux à mettre en place... ;)


merci de vos réponses
notre partenaire part sur du HS512

Merci de vos codes qui vont bien nous inspirer.
Bon we

--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Posté le 15 mars 2022 - 08:45
Roumegou avait écrit le 11/03/2022 :
bchanudet a formulé la demande :
Bonjour,

Un peu dans la même veine, voilà ce que j'ai :

PROCÉDURE GenereJWT()

vHeaders est un Variant
vPayload est un Variant

sCléSecrète est une chaîne = "CeciEstMaCléSecrète"

vHeaders.alg = "HS256"
vHeaders.typ = "JWT"

vPayload.iss = "TestWinDev" // issuer
vPayload.iat = DateHeureVersEpoch(DateHeureSys()) // issued at
vPayload.sub = "test" // subject
vPayload.exp = DateHeureVersEpoch(DateHeureSys()) + 20*60 // expire at
(maintenant + 20 minutes)

// payload spécifique à l'application
vPayload.role = "admin"

sEncodedHeaders est une chaîne =
Remplace(Encode(ChaîneVersUTF8(VariantVersJSON(vHeaders,psdMinifié)),encodeBASE64URL),"=",
"")
sEncodedPayload est une chaîne =
Remplace(Encode(ChaîneVersUTF8(VariantVersJSON(vPayload,psdMinifié)),encodeBASE64URL),"=",
"")

// génération de la signature
sSignature est une chaîne =
Remplace(Encode(HashChaîne(HA_HMAC_SHA_256,sEncodedHeaders + "." +
sEncodedPayload,ChaîneVersUTF8(sCléSecrète)),encodeBASE64URL),"=","")

RENVOYER sEncodedHeaders + "." + sEncodedPayload + "." + sSignature


PROCÉDURE VérifieJWT(sJWT est une chaîne) : booléen

sCléSecrète est une chaîne = "CeciEstMaCléSecrète"
jHeaders est un JSON jPayload est un JSON

// Séparation du JWT
tabParties est un tableau de chaînes
sJWT.VersTableau(tabParties,".")

// On attend trois morceaux : headers + payload + signature
SI PAS tabParties..Occurrence = 3 ALORS Trace("Le JWT n'est pas complet")
RENVOYER Faux
FIN

// On vérifie l'algorithme souhaité
QUAND EXCEPTION DANS
jHeaders..FormatJSON = (Décode(tabParties[1],encodeBASE64))
FAIRE
Trace("Les entêtes ne sont pas formatées au format JSON")
RENVOYER Faux
FIN

SI PAS jHeaders.alg..Existe ALORS
Trace("L'algorithme de signature n'est pas spécifié")
RENVOYER Faux
FIN

// On vérifie la signature en fonction de l'algorithme décrit.
SELON jHeaders.alg
CAS "HS256": sSignature est une chaîne =
Remplace(Encode(HashChaîne(HA_HMAC_SHA_256,tabParties[1] + "." +
tabParties[2],ChaîneVersUTF8(sCléSecrète)),encodeBASE64URL),"=","")
SI tabParties[3] <> sSignature ALORS
Trace("La signature ne correspond pas", tabParties[3], sSignature)
RENVOYER Faux
FIN
AUTRE CAS
Trace("Aucun algorithme correspondant", jHeaders.alg)
RENVOYER Faux
FIN


// On vérifie les attributs standard du payload
QUAND EXCEPTION DANS jPayload..FormatJSON = (Décode(tabParties[1],
encodeBASE64))
FAIRE
Trace("Le payload n'est pas formaté au format JSON")
RENVOYER Faux
FIN

// Le token a-t-il expiré ?
SI jPayload.exp..Existe ALORS
SI DateHeureVersEpoch(DateHeureSys()) > jPayload.exp ALORS
Trace("Le JWT a expiré", EpochVersDateHeure(jPayload.exp))
RENVOYER Faux
FIN
FIN

// Insérer ici d'autres contrôles métier

RENVOYER Vrai


Attention cependant, l'algorithme HMAC-SHA-256 (ou HS256 dans les JWT)
n'est qu'un seul des algorithmes que le JWT peut utiliser. C'est le seul
requis par les standards, mais il y en a d'autres. Et les autres sont un
peu plus fastidieux à mettre en place... ;)

merci de vos réponses
notre partenaire part sur du HS512

Merci de vos codes qui vont bien nous inspirer.
Bon we


Bonjour à tous
encore merci de vos aides.
A noter ce site génial pour produire des jetons de tests

https://jwt.io/

Voici notre code sur du HS512
PROCÉDURE JWTAuth()

Authorization est une chaîne =
WebserviceLitEntêteHTTP("Authorization")
token est une chaîne = ExtraitChaîne(Authorization,2," ")
vParam est un Variant = SetEnvironnement()
codesecret est une chaîne = vParam.code
verifTokenCode est un Variant = VerifyToken(token,codesecret)


SI verifTokenCode.Status="OK" ALORS

payload est un chaîne =
Décode(ExtraitChaîne(token,2,"."),encodeBASE64)
payloadVariant est un Variant = JSONVersVariant(payload)
codeUser est une chaîne = payloadVariant.sub

vUser est un Variant
NumConnexion est un entier = ConnexionBase()
vUser = GetUser(codeUser,NumConnexion)

SI vUser.Status = "INVALID_USER" ALORS
WebserviceEcritCodeHTTP(404)
FIN
retourJson est une chaîne = VariantVersJSON(vUser)

RENVOYER retourJson

SINON
WebserviceEcritCodeHTTP(400,VariantVersJSON(verifTokenCode))
FIN




A noter que nous avons choisi de passer le token dans les entêtes http
sous le code Authorization, pratique qui tend à être un standard

et la procédure VerifYToken

PROCÉDURE VerifyToken(token est une chaîne,codesecret est une chaîne)

header est une chaîne
payload est une chaîne
signature est une chaîne
signaturegenere est une chaîne
bufferheader est un Buffer
buffpayload est un Buffer

payloadVariant est un Variant
timestampactuel est un entier= DateHeureVersEpoch(DateSys())

header=Décode(ExtraitChaîne(token,1,"."),encodeBASE64)
payload =Décode(ExtraitChaîne(token,2,"."),encodeBASE64)
signature = ExtraitChaîne(token,3,".")

payloadVariant = JSONVersVariant(payload)
bufferheader = header
buffpayload = payload
signaturegenere =
HashChaîne(HA_HMAC_SHA_512,(Encode(bufferheader,encodeBASE64URL)+"."+Encode(buffpayload,encodeBASE64URL)),codesecret)

signaturegenere = Encode(signaturegenere,encodeBASE64URL)
signaturegenere = Gauche(signaturegenere,Taille(signaturegenere)-2)

vRetour est un Variant
SI signaturegenere <> signature ALORS
vRetour.Status = "INVALID_TOKEN"
SINON SI timestampactuel > payloadVariant.iat ALORS
vRetour.Status = "EXPIRED_TOKEN"
SINON
vRetour.Status = "OK"
FIN
RENVOYER vRetour


--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Posté le 22 septembre 2022 - 15:31
Bonjour Roumegou , le sujet date un peu mais auriez vous le code en entier de votre exemple de webservice , car il me manque le détail de certaines procédures il y a pas d'exemples chez pc soft ou sur le web de code webservice windev/webdev coté serveur qui gère tout cela...
identification user , param , fabrication token , vérification token , transmission etc...
Posté le 22 septembre 2022 - 15:49
Michel vient de nous annoncer :
Bonjour Roumegou , le sujet date un peu mais auriez vous le code en entier de
votre exemple de webservice , car il me manque le détail de certaines
procédures il y a pas d'exemples chez pc soft ou sur le web de code
webservice windev/webdev coté serveur qui gère tout cela...
identification user , param , fabrication token , vérification token ,
transmission etc...


Bonjour

je crois que j'avais tout donné ??
à part des focntions persos qui ne concernent que nous comme

SetEnvironnement() qui permet d'initier des variables globales avec des
paramètres

NumConnexion est un entier = ConnexionBase()

code pour se connecter à nos bases ici en l'occurrence sqlserver


vUser = GetUser(codeUser,NumConnexion)
va lire notre base pour récupérer l'id en lisant notre base de la
personne qui se connecte; donc c'est spécifique à notre service

--
Cet e-mail a été vérifié par le logiciel antivirus d'Avast.
www.avast.com
Membre enregistré
36 messages
Posté le 11 octobre 2022 - 00:30
Bonjour,

N'ayant rien trouvé de disponible, et ne voulant pas recréer ce système de JWT à chaque projet, j'en ai fait un composant disponible sur GitHub, accessible à tous.

https://github.com/WDRomainSimon/COMPOSANT_JWT

Vous avez juste à l'importer et utiliser les fonctions comme décrit dans le README.
Posté le 01 décembre 2024 - 18:23
Bonjour,

Je vois que ce code concerne les webservices, mais peut-on integrer le JWT dans les projets WebDev page dynamique en mode session (les pages qui contiennent la partir navigateur et serveur) ?
Je n'arrive pas a comprendre le moyen de communication entre la partie navigateur et la partie serveur (REST ou SOAP ou autre chose) pour voir comment ajouter le JWT