|
FORUMS PROFESSIONNELS WINDEV, WEBDEV et WINDEV Mobile |
| | | | | |
Accueil → WINDEV 2024 → Authentification OAuth 2.0 d'application à serveur (sans popin d'autorisation) |
Authentification OAuth 2.0 d'application à serveur (sans popin d'autorisation) |
Débuté par Nico, 27 déc. 2016 18:31 - 13 réponses |
| |
| | | |
|
| |
Membre enregistré 122 messages Popularité : +5 (5 votes) |
|
Posté le 27 décembre 2016 - 18:31 |
J'essaye désespérément d'effectuer une Authentification OAuth 2.0 d'application Windev à serveur Voir la page suivante : https://developers.google.com/identity/protocols/OAuth2ServiceAccount…
Cette authentification permet de connecter les utilisateurs d'une application Windev vers les services de Google sans popin d'Authentification (Par exemple pour effectuer des transferts vers Google Drive sans que l'utilisateur soit obligé de connaitre le login/pass du compte Google drive => G suite)
Mon problème est que Google me renvoi toujours le Jeton d'erreur suivant : { "error": "invalid_grant", "error_description": "Invalid JWT Signature." }
J'ai effectué plus d'une centaines de test et je sais que c'est la fonction HashChaîne qui ne me renvoi pas le bon résultat car si mes valeurs sJwtHeader ou sJwtClaim sont mauvaises, j'ai un autre message d'erreur.
Voici une partie du code
duExp est une Durée duIat est une Durée dhRef est une DateHeure = "19700101000000" dhMaintenant est une DateHeure = DateHeureLocaleVersUTC(DateSys()+HeureSys())
duIat = dhMaintenant - dhRef duExp = duIat duExp..Heure += 1
sJwtHeader est une chaîne ANSI = [ {"alg":"RS256","typ":"JWT"} ]
sJwtClaim est une chaîne ANSI = "{"+... """iss"":""xxxxxxxxx@xxxxxxxxx.iam.gserviceaccount.com"","+... """scope"":""https://www.googleapis.com/auth/drive"","+... """aud"":""https://www.googleapis.com/oauth2/v4/token"","+... """exp"":"+PartieEntière(duExp..EnSecondes)+","+... """iat"":"+PartieEntière(duIat..EnSecondes)+... "}"
Base64Header est une chaîne ANSI = SansCaractèreDroite(Crypte(sJwtHeader, "", compresseAucun+crypteAucun, encodeBASE64), "=") Base64Claim est une chaîne ANSI = SansCaractèreDroite(Crypte(sJwtClaim, "", compresseAucun+crypteAucun, encodeBASE64), "=")
private_key est une chaîne ANSI = ""+... "-----BEGIN PRIVATE KEY-----"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"+Caract(10)+... Caract(10)+"-----END PRIVATE KEY-----"+Caract(10)+... ""
bufHash est un Buffer = HashChaîne(HA_HMAC_SHA_256, Base64Header+"."+Base64Claim, private_key)
sSHA256 est une chaîne ANSI = SansCaractèreDroite(Crypte(bufHash, "", crypteAucun+compresseAucun, encodeBASE64), "=") sSHA256 = Remplace(sSHA256, "+", "-") sSHA256 = Remplace(sSHA256, "/", "_")
maRequete est une HTTPRequête maRequete..URL = "https://www.googleapis.com/oauth2/v4/token" maRequete..Méthode = httpPost
HTTPCréeFormulaire("jeton") HTTPAjouteParamètre("jeton", "grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer") HTTPAjouteParamètre("jeton", "assertion", Base64Header+"."+Base64Claim+"."+sSHA256)
cMaRéponse est un httpRéponse = HTTPEnvoieFormulaire("jeton", maRequete)
SI ErreurDétectée ALORS Erreur(ErreurInfo(errComplet)) SINON Info(cMaRéponse..Contenu) FIN
C'est la que j'obtient dans la variable cMaRéponse..Contenu { "error": "invalid_grant", "error_description": "Invalid JWT Signature." }
Mon code peut paraître être du charabia, mais si quelqu'un s'est déjà penché sur ce type de problème, il comprendra mes difficultés
Sinon j'espère que mon code pourra donner quelques pistes aux personnes qui débute avec Oauth2 de Google pour une authentification sans popin (avec popin c'est ce que font les nouvelles fonctionnalités de Windev 22). Et qu'ils puissent ensuite me donner des pistes |
| |
| |
| | | |
|
| | |
| |
Posté le 03 janvier 2017 - 17:03 |
Bonjour, Nous allons être confronté à la même difficulté que vous dans quelques jours. Dans l'entête, vous indiqué comme algo RS256 et ensuite vous crypté en SHA256. Avez-vous essayé de passer en algo HS256 plutôt ?
En tout cas, si vous avez la solution, elle m'intéresse ... |
| |
| |
| | | |
|
| | |
| |
Membre enregistré 122 messages Popularité : +5 (5 votes) |
|
Posté le 04 janvier 2017 - 08:39 |
Bonjour Steeve,
Dans la documentation de Google ils indiquent d'utiliser "RSA SHA-256" ce qui correspond pour eux à RS256 dans le fichier d'entête. Pour le moment j'ai mis le projet en stand-by (ce n'était pas une priorité pour nous, il s'agissait plutôt de R&D avec les services Google pour en analyser les possibilités d'intégration dans une application).
Si vous arrivez à mettre en oeuvre la solution, je suis intéressé de savoir ce que j'avais fait de travers
Bonne journée |
| |
| |
| | | |
|
| | |
| |
Membre enregistré 122 messages Popularité : +5 (5 votes) |
|
Posté le 12 mai 2017 - 14:45 |
Je viens de poursuivre mes tests que j'avais laissé de côté au mois de Décembre, et je n'arrive toujours pas à m'identifier sur les serveurs de Google avec Windev. J'y arrive parfaitement depuis PHP en portant mon code. Mais je pense que dans Windev la ligne
bufHash est un Buffer = HashChaîne(HA_HMAC_SHA_256, Base64Header+"."+Base64Claim, private_key)
N'est pas adapter ou fausse...
En PHP j'utilise
openssl_sign($signing_input, $Base64Header.".".Base64Claim, $private_key, OPENSSL_ALGO_SHA256);
Et ça fonctionne parfaitement
Quelque saurait quel est l'équivalent de la methode "openssl_sign" en Windev ou comment la porter ?
Bonne journée
-- Nicolas Gonot - 2exVia Agence de communication multimédia depuis 1996 http://www.2exvia.com |
| |
| |
| | | |
|
| | |
| |
Membre enregistré 122 messages Popularité : +5 (5 votes) |
|
Posté le 29 mai 2017 - 09:40 |
Pour ceux que ça intéresse, je vous invite à tester l'exemple "WD Oauth JWT", fournit dans le CD-ROM du TDF Tech 2017, pour faire de l'authentification serveur à serveur. L'obtention d'un jeton d'identification fonctionne parfaitement
-- Nicolas Gonot - 2exVia Agence de communication multimédia depuis 1996 http://www.2exvia.com |
| |
| |
| | | |
|
| | |
| |
Posté le 31 mai 2017 - 09:15 |
Identification Oauth2 ne pose heureusement pas trop de problèmes! mais pour ce qui est du cryptage entre windev, windev mobile et un site web là ... . Le cryptage "CrypteStandard" vous donnera beaucoup plaisir! Un truc pour un bizutage un lundi matin - openssl_sign($signing_input, $Base64Header.".".Base64Claim, $private_key, OPENSSL_ALGO_SHA256); - |
| |
| |
| | | |
|
| | |
| |
Posté le 11 mars 2021 - 18:03 |
Bonjour ,
j'ai le même problème. Avez-vous enfin trouvé la solution? Si oui, pouvez-vous ajouter le code correcte?
merci beacoup Kurt |
| |
| |
| | | |
|
| | |
| |
Membre enregistré 122 messages Popularité : +5 (5 votes) |
|
Posté le 12 mars 2021 - 09:08 |
Je passe finalement par un webservice que j'ai écrit en PHP, Windev interroge et communique avec ce webservice
-- Nicolas Gonot - 2exVia Agence de communication multimédia depuis 1996 http://www.2exvia.com |
| |
| |
| | | |
|
| | |
| |
Posté le 12 mars 2021 - 09:13 |
ok, merci pour votre réponse. |
| |
| |
| | | |
|
| | |
| |
Membre enregistré 16 messages |
|
Posté le 22 février 2022 - 05:51 |
Bonjour,
voici un code qui permet de récupérer un token oAuth de l'API Microsoft Graph pour une utilisation de serveur à serveur, sans besoin d'authentification d'un utilisateur. Je me suis basé sur la doc Microsoft suivante : https://docs.microsoft.com/fr-fr/graph/auth-v2-service
Bon OK, ce n'est pas pour Google, mais ça peu aider pour ceux qui comme moi sont tombés sur ce post quand j'ai cherché une solution de serveur à serveur pour Microsoft. La solution d'utiliser l'exemple "WD Oauth JWT" proposée par Nico ci-dessus ne fonctionne plus à cause que Microsoft a supprimé l'authentification ACS en 2018.
sEmailUser_quiDoitSeConnecterEnTantQuApplication est une chaine = "monUtilisateur@nomEntreprise.fr"
sO365_ClientID est une chaîne = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
sO365_ClientSecret est une chaîne = "xxxxxxxxxxxxxxxxxxxxxxxxx"
dO365_ClientSecret_Expiration est une Date = "20240101"
sO365_Tenant est une chaîne = "nomEntreprise.fr"
sScope est une chaîne = "https://graph.microsoft.com/.default"
bOkDate est un booleen = VRAI SI dO365_ClientSecret_Expiration < DateSys() ALORS Erreur("Le ClientSercret Office 365 a expiré"+RC+"Veuillez le renouveler") bOkDate = FAUX SINON dDatesysPlus3Mois est une Date = DateSys() dDatesysPlus3Mois..Mois +=3 SI dO365_ClientSecret_Expiration < dDatesysPlus3Mois ALORS Info("Le ClientSercret Office 365 va expirer le "+DateVersChaîne(dO365_ClientSecret_Expiration)+RC+"Veuillez le renouveler rapidement") FIN FIN
Si bOkDate ALORS MonHttpRequ est un HTTPRequête MonHttpRequ.Méthode = httpPost MonHttpRequ..URL = "https://login.microsoftonline.com/[%sO365_Tenant%]/oauth2/v2.0/token" sContenu est une chaîne = [ client=%1&client_id=%2&scope=%3&client_secret=%4&grant_type=client_credentials ] sContenu = ChaîneConstruit(sContenu,sEmailUser_quiDoitSeConnecterEnTantQuApplication,sO365_ClientID,sScope,sO365_ClientSecret) MonHttpRequ..Contenu = sContenu HttpMaReponse est un httpRéponse = HTTPEnvoie(MonHttpRequ) SI HttpMaReponse.CodeEtat = 200 ALORS oAuth2Param est un OAuth2Paramètres oAuth2Param.ClientID = sO365_ClientID oAuth2Param.ClientSecret = sO365_ClientSecret oAuth2Param.URLAuth = "https://login.microsoftonline.com/[%sO365_Tenant%]/oauth2/v2.0/token" oAuth2Param.Scope = "https://graph.microsoft.com/.default" oAuth2Param.URLToken = "https://login.microsoftonline.com/[%sO365_Tenant%]/oauth2/v2.0/token" MonToken est un AuthToken(oAuth2Param, HttpMaReponse.Contenu) gnMontoken <= MonToken FIN
SI gnMontoken = Null ALORS Erreur("La connexion à Office 365 a échouée"+RC+"Token null") RENVOYER FAUX SINON SI gnMontoken.Valide = FAUX ALORS Erreur("La connexion à Office 365 a échouée"+RC+gnMontoken.RéponseServeur) RENVOYER FAUX SINON Info("token valide jusqu'au " + DateHeureVersChaîne(gnMontoken.DateExpiration))
RENVOYER VRAI FIN FIN SINON RENVOYER FAUX FIN
Une fois le token récupéré, on peut l'utiliser de la même manière que si un utilisateur s'était connecté, bien qu'il y ai quelques différences sur les autorisations disponibles (voir le site de Microsoft : https://docs.microsoft.com/fr-fr/graph/auth-v2-service )Message modifié, 22 février 2022 - 06:38 |
| |
| |
| | | |
|
| | |
| |
Membre enregistré 16 messages |
|
Posté le 22 février 2022 - 06:10 |
A noter une différence lorsqu'on utilise un token en tant qu'application pour récupérer des infos sur un utilisateur : l'URL d'appel dans la requête HTTP.
Voici un exemple : pour récupérer les contacts d'un utilisateur avec un token récupéré "en tant qu'application", l'URL d'appel doit être comme ceci :
cMyRequestHTTPsend..URL = "https://graph.microsoft.com/v1.0/users/"+sEmailUser+"/contacts"
alors qu'un appel avec un token en tant qu'utilisateur doit être ceci :
cMyRequestHTTPsend..URL = "https://graph.microsoft.com/v1.0/me/contacts" |
| |
| |
| | | |
|
| | |
| |
Posté le 30 août 2022 - 16:37 |
Bonjour, Quentin, grâce à ton code et en utilisant mes paramètres j'obtient bien mon Token. Par contre, lorsque je l'utilise pour envoyer ou recevoir des mails, j'ai à chaque fois une erreur : En réception : Session IMAP, accès refusé La dernière réponse du serveur IMAP est : 04 NO LOGIN failed
Session IMAP, accès refusé La dernière réponse du serveur IMAP est : 03 NO AUTHENTICATE failed
et en envoi : Session SMTP, accès refusé
Je suis sur de mes login et mot de passe
Je câle . . .
Une aide serait la bienvenue
Cordialement |
| |
| |
| | | |
|
| | |
| |
Posté le 28 novembre 2022 - 16:17 |
Bonjour à tous, Même problème ici, récupération sans soucis du token "application" mais message d'erreur pour exploiter l'ouverture d'une session imap ou pour envoyer un mail smtp .... Avez vous trouvé la solution ? Cordialement |
| |
| |
| | | |
|
| | |
| |
Posté le 02 février 2024 - 14:29 |
Bonjour,
Je me permets de relancer le sujet. J'ai le même besoin pour utiliser l'API de Docusign avec Webdev 27.
Malheureusement, le composant Docusign (version 2024) fonctionne mais avec une authentification : Authorization Code Grant -> à chaque appel pour faire signer un document, il faut que l'utilisateur soit connecté. Si ce n'est pas le cas, un login / mdp lui ait demandé (identification Docusign)
J'aimerai donc utiliser l’authentification : JWT Grant -> celle ci permet d'envoyer des documents à Docusign sans s'identifier sur Docusign (donc transparent pour l'utilisateur final).
Comme j'ai compris, voici les étapes à suivre :
1) Créer un compte développeur sur Docusign -> OK 2) Créer l'application dans "APP and Keys" -> OK 3) Demande d'autorisation de demande -> OK
4) Créer un JWT -> là, ça se complique, j'ai tenté plusieurs choses mais ça ne fonctionne pas -> Signature invalide quand test sur le site https://jwt.io/
5) Obtenir le jeton d'accès -> A faire une fois l'étape précédente OK
Je pense que le problème vient du crytage de la signature... Quelqu'un a déjà fait cela ?
Merci d'avance |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|