PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV 2024 → Authentification Office 365 via Azure et AuthIdentifie
Authentification Office 365 via Azure et AuthIdentifie
Started by Ferbak, Oct., 04 2019 12:41 PM - 12 replies
Registered member
50 messages
Posted on October, 04 2019 - 12:41 PM
Bonjour à tous,

Une fois n'est pas coutume, après avoir tout essayé et fait toutes les recherches possibles, je me tourne vers mon ultime recours :)

Je voudrais synchroniser l'agenda Outlook avec une application et je bloque déjà au niveau de la récupération du Token.

J'ai fait ma configuration via la nouvelle plateforme Microsoft Azure mais avec tous les changements récents, la doc disponible est énorme et je me perds dans toutes les combinaisons possibles.

J'ai inscrit mon application et j'ai donc mon
- IdClient(d'application)
- IdLocataire (annuaire)
- IdObjet (pas utilisé)

J'ai configuré un
- SecretClient
- Une autorisation d'application Calendars.Read de type Application (non déléguées) sur Exchange et Microsoft Graph

Types de comptes
C'est configuré sur "Comptes dans cet annuaire d'organisation uniquement" (pas "Comptes dans un annuaire d'organisation")


Scope

Le scope fonctionne, si je modifie les droits, j'ai une erreur de droits d'accès donc je présume que si ça passe, ce qu'est tout va bien à ce niveau la

https://graph.microsoft.com/Calendars.Read (https://outlook.office365.com/Calendars.Read fonctionne aussi)


UrlAuth

Après avoir testé : https://login.microsoftonline.com/common/oauth2/v2.0/authorize
j'avais des soucis, soit je devais changer le type de compte, soit utiliser les points de terminaison, j'ai donc utilisé mon IdLocataire à la place de "common" comme suggéré dans le panneau de config des points de terminaison :
https://login.microsoftonline.com/*IdLocataire */oauth2/v2.0/authorize

Token

Idem, j'ai utilisé
https://login.microsoftonline.com/*IdLocataire/oauth2/v2.0/token


URLRedirection

C'est ici que les soucis se posent. J'ai essayé un peu tout, que ce soit de type "Web" (avec ou sans octroi implciite) ou "Bureau + appareils" parmi ce que j'ai pu trouvé et ce qui m'était proposé.

Bien que ce paramètre soit indiqué comme facultatif, si je n'en mets pas dans la config, j'ai ce message d'erreur dans la fenêtre web de connexion qui s'ouvre:
AADSTS500113: No reply address is registered for the application.
Si j'en mets un dans la config Azure mais rien dans mon code:
AADSTS50011: The reply url specified in the request does not match the reply urls configured for the application: '*IdClient'
Si j'en mets un dans la config et dans mon code :
Pas d'erreur mais mon AuthIdentifie renvoie "Faux"

Voici ceux que j'ai testé
msal*IdClient*://auth
https://login.live.com/oauth20_desktop.srf
https://login.microsoftonline.com/common/oauth2/nativeclient
https://login.microsoftonline.com/*IdLocataire*/oauth2/nativeclient
urn:ietf:wg:oauth:2.0:oob

Si je mets du http://localhost ou http://localhost:80 comme j'ai pu voir sur ce forum,, mon navigateur s'ouvre mais attend une réponse.

Entre tous ces tests, je suis un peu perdu. J'ai un peu le sentiment de tourner autour vu qu'en fonction de mes corrections j'ai de moins en moins de messages d'erreur, mais je reste malgré tout impuissant ici.

Si quelqu'un pouvait m'éclairer, je suis lui en serai très reconnaissant.

Merci d'avance et bonne après-midi,

Ferbak
Registered member
50 messages
Posted on October, 05 2019 - 10:07 AM
Re,

Ayant continué à chercher entre temps, je reviens avec une solution qui me donne, enfin, une réponse.

J'a donc utilisé http://localhost:XXXX où XXXX est un port choisi au hasard comme adresse de redirection. J'avais ouvert ces ports dans mon pare-feu sur l'exe test de windev, mais ça s'est révélé facultatif.

Là où c'était plus particulier, c'est que la plateforme utilisée dans la configuration Azure est de type WEB et pas Bureau.

En procédant ainsi, j'ai mon token en réponse.

Voilà, si ça peut aider quelqu'un un jour :)

Bon weekend,

Ferbak
Registered member
133 messages
Popularité : +3 (3 votes)
Posted on December, 17 2019 - 3:37 PM
Aprés des heures et des heures, j'ai pu me connecter. C'est bien le reply adresse qui pose probleme.

Voici mon code :
OAuth2Params est OAuth2Paramètres
OAuth2Params..ClientID = "XXXX"
OAuth2Params..ClientSecret = "XXXX"
OAuth2Params..URLAuth = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
OAuth2Params..URLToken = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
SI EnModeTest() = Faux ALORS
OAuth2Params..URLRedirection = "https://NOTRE-SERVEUR/WD230AWP/WD230Awp.exe/OAUTH2_RETOUR"
SINON
OAuth2Params..URLRedirection = "http://localhost/WD230AWP/WD230Awp.exe/OAUTH2_RETOUR"
FIN
OAuth2Params..ParamètresSupplémentaires = "force_reapprove=false"
OAuth2Params..Scope = "offline_access User.Read"
MonToken est un AuthToken = AuthIdentifie(OAuth2Params)

MonToken = AuthIdentifie(OAuth2Params)

SI MonToken.Valide = Faux ALORS
Info("Erreur de connexion")
SINON
Info("Connexion ok")
FIN

Et ca, cela fonctionne si vous rajouter les 2 adresses dans les URL de retour AZURE.
Message modified, December, 17 2019 - 4:08 PM
Registered member
324 messages
Popularité : +21 (51 votes)
Posted on December, 17 2019 - 4:17 PM
SI EnModeTest() = Faux ALORS
OAuth2Params..URLRedirection = "https://NOTRE-SERVEUR/WD230AWP/WD230Awp.exe/OAUTH2_RETOUR"
SINON
OAuth2Params..URLRedirection = "http://localhost/WD230AWP/WD230Awp.exe/OAUTH2_RETOUR"
FIN


Effectivement il faut préciser les url de redirection dans windev
En webdev ce n'est pas modifiable
En mobile android (celà ne fonctionne que sur un seul et unique port, ios aucune idée)

Particularités
- En prod si l'url n'est pas en https, aucune OAuth n'est activable
- L'url de redirection doit être déclarer dans Azure, dans les urls de retour, c'est tout ^^.
- Vous pouvez utiliser un AD maison, ici on utilise un Azure "Interne"
Registered member
948 messages
Popularité : +11 (13 votes)
Posted on April, 22 2020 - 6:57 PM
Bonjour,

/OAUTH2_RETOUR c'est une page web, ou juste un url bateau ?

Merci

OB
Registered member
11 messages
Posted on April, 12 2021 - 4:20 PM
Bonjour,

J'essaye de faire fonctionner cette solution, mais sans succès.
Plus exactement, cela a fonctionné deux fois, mais la plupart du temps, ce n'est pas OK.

J'ai essayé de changer ParamètresSupplémentaires (j'avais vu "force_reapprove=false" ou "display=popup"), mais pas mieux
J'ai essayé différents schéma d'url, mais pas mieux.

Le comportement est le suivant : lorsque j'appelle AuthIdentify dans le code, j'ai une fenêtre Windows qui s'ouvre et se met en attente. Mon navigateur s'ouvre alors et je passe dans l'authentification microsoft (c'est invisible) pour être redirigé vers mon url de retour (en localhost). La fenêtre Windows se ferme alors, mais ma variable token retournée par AuthIdentify ne semble pas valide.

Cela a fonctionné deux fois (une fois la semaine passée et une fois aujourd'hui), donc c'est vraiment étrange comme comportement et je ne vois pas où peu se situer le problème.

Merci de votre aide.
Registered member
11 messages
Posted on April, 13 2021 - 2:59 PM
Pour les personnes intéressées, j'ai probablement trouvé la solution à mon problème.

Le problème semble se situer au niveau du ClientSecret qui est mentionné dans la documentation.
D'après la théorie, le secret ne doit être utilisé que si le code n'est pas exposé.
Dans un client Windev, application Windows destinée à être installée sur un PC utilisateur, le code est donc exposé et le secret ne doit pas être utilisé.
Suffit donc de ne pas mentionner le secret et cela fonctionne.

Autre solution, au niveau de la déclaration de l'application dans l'Azure Active Directory, on indique que c'est une application web (et pas une application Windows comme ci-dessus) et dans ce cas, le secret peut être mis dans l'application Windev.

A priori, c'est la première solution qui correspond à la théorie si j'ai bien compris ...
Posted on July, 29 2021 - 3:46 PM
Bonjour à tous,

j'ai passé un peu de temps sur le sujet et j'ai réussi face à ce sujet, merci à tous les contributeurs. Je vais également apporter ma pierre à l'édifice.

J'ai écrit un code qui fonctionne pour Windev et Webdev qui permet la connexion oauth2 à office 365 et la récupération de l'adresse mail et de l'identifiant Office 365 de l'utilisateur office 365 connecté.

Voici le code que j'ai un peu remanié pour le présenter ici :
//Il faut commencer par ajouter une application dans https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade


//ID d'application consultable dans "Vue d'ensemble"
gsO365_ClientID est une chaîne = "<A RENSEIGNER>"


// Le Secret client doit être généré dans "Certificats et secrets"
//Valeur du Secret client
gsO365_ClientSecret est une chaîne = "<A RENSEIGNER>"

//Date d'expiration du secrect client => afin d'avertir l'administrateur à l'approche de l'expiration
gdO365_ClientSecret_Expiration est une Date = "<A RENSEIGNER>"

//Nom du tenant ou l'application a été déclarée. Il est de la forme monentreprise.onmicrosoft.com
gsO365_Tenant est une chaîne = "<A RENSEIGNER>.onmicrosoft.com"


//Les URI de redirections doivent être ajoutée dans "Authentification"
//URI de type WEB
//Pour la production, attention la forme de cette URI est fixe, il faut simplement renseigner le nom de domaine de votre serveur
gsO365_URICallBack_WEB est une chaîne = "https://<A RENSEIGNER>/WD260AWP/WD260Awp.exe/OAUTH2_RETOUR"
//Pour le mode test
gsO365_URICallBack_WEB_Test est une chaîne = "http://localhost/WD260AWP/WD260Awp.exe/OAUTH2_RETOUR"

//URI de type application de bureau.
gsO365_URICallBack_APP est une chaîne = "http://localhost:9874"


SI gdO365_ClientSecret_Expiration<DateSys() ALORS
Erreur("Le ClientSercret Office 365 a expiré"+RC+"Veuillez le renouveler")
SINON
dDatesysPlus3Mois est une Date = DateSys()
dDatesysPlus3Mois..Mois +=3
SI gdO365_ClientSecret_Expiration<dDatesysPlus3Mois ALORS
Info("Le ClientSercret Office 365 va expirer le "+DateVersChaîne(gdO365_ClientSecret_Expiration)+RC+"Veuillez le renouveler rapidement")
FIN
OAuth2Params est OAuth2Paramètres
OAuth2Params..ClientID = gsO365_ClientID
OAuth2Params..URLAuth = "https://login.microsoftonline.com/[%gsO365_Tenant%]/oauth2/v2.0/authorize"
OAuth2Params..URLToken = "https://login.microsoftonline.com/[%gsO365_Tenant%]/oauth2/v2.0/token"


<Compile SI TypeConfiguration=Site>
//Le secret client ne doit pas etre renseigné pour application de bureau
OAuth2Params..ClientSecret = gsO365_ClientSecret
SI EnModeTest() ALORS
OAuth2Params..URLRedirection = gsO365_URICallBack_WEB_Test
SINON
OAuth2Params..URLRedirection = gsO365_URICallBack_WEB
FIN
<SINON>
OAuth2Params..URLRedirection = gsO365_URICallBack_APP
<FIN>

OAuth2Params..ParamètresSupplémentaires = "force_reapprove=false"

//Ajouter user.read dans "API autorises" pour lire les informations de l'utilisateur connecté
OAuth2Params..Scope = "offline_access User.Read"

MonToken est un AuthToken = AuthIdentifie(OAuth2Params)
MonToken = AuthIdentifie(OAuth2Params)

SI MonToken.Valide = Faux ALORS
Erreur("La connexion à Office 365 a échouée"+RC+MonToken.RéponseServeur)
SINON
// Lecture
oRequête est une httpRequête
oRequête.Méthode = httpGet
oRequête.URL = "https://graph.microsoft.com/v1.0/me"
oRequête.ContentType = "application/json"
oRequête.AuthToken = MonToken
// On ajoute l'entête 'Prefer: odata.track-changes' pour obtenir les changements depuis le dernier appel (sinon, les données ne sont pas mises à jour)
oRequête.Entête["Prefer"] = "odata.track-changes"
Réponse est une httpRéponse
jsRéponse est un JSON
// Exécute la requête
Réponse = HTTPEnvoie(oRequête)

SI ErreurDétectée ALORS
Erreur("La requête HTTP à Office 365 a échouée"+RC+ErreurInfo())
RENVOYER Faux
SINON
jsRéponse = Réponse..Contenu
// Le serveur a renvoyé une erreur
SI jsRéponse.Error..Existe ALORS

Erreur("La requête à Office 365 a échouée"+RC+jsRéponse.Error.Message)
SINON
sMail_O365_UtilisateurConnecté est une chaîne = jsRéponse.mail
sId_O365_UtilisateurConnecté est une chaîne = jsRéponse.userPrincipalName
FIN
FIN
FIN


FIN
Posted on August, 02 2021 - 9:36 AM
Super, merci pour ce code concis et clair.
:merci:
Registered member
1 message
Posted on August, 02 2021 - 2:16 PM
Petite précisions, il faut supprimer la ligne ci-dessous si vous souhaiter relire à chaque requête le JSON de l'utilisateur connecté, dans le cas contraire la réponse à https://graph.microsoft.com/v1.0/me est bien de type 200 pour OK mais elle ne contient pas de JSON.

//A supprimer pour lire le JSON à chaque requete.
oRequête.Entête["Prefer"] = "odata.track-changes
Registered member
17 messages
Popularité : +1 (1 vote)
Posted on February, 10 2022 - 11:58 AM
Bonjour à tous, et merci pour ces explications.
Avez-vous une solution pour la déconnexion ?
Ex : un lien déconnexion oblige les fois suivantes à s'authentifier de nouveau ?
Registered member
133 messages
Popularité : +3 (3 votes)
Posted on August, 23 2022 - 1:54 PM
je déterre le sujet parce qu'on me demande de m'y remettre.

Alors, j'arrive a passer l'authentification, sans erreur de redirection uri.

Mais malheureusement, le token est vide.

//ID d'application consultable dans "Vue d'ensemble"
gsO365_ClientID est une chaîne = "f46de762-94ed-47a3-a633-xxxxxxxx"

// Le Secret client doit être généré dans "Certificats et secrets"
//Valeur du Secret client
gsO365_ClientSecret est une chaîne = "0b868189-7a78-4381-837a-xxxxxxxx"

//Nom du tenant ou l'application a été déclarée. Il est de la forme monentreprise.onmicrosoft.com
gsO365_Tenant est une chaîne = "xxxxGroup.onmicrosoft.com"

OAuth2Params est OAuth2Paramètres
OAuth2Params..ClientID = gsO365_ClientID
OAuth2Params..URLAuth = "https://login.microsoftonline.com/[%gsO365_Tenant%]/oauth2/v2.0/authorize"
OAuth2Params..URLToken = "https://login.microsoftonline.com/[%gsO365_Tenant%]/oauth2/v2.0/token"

//Le secret client ne doit pas etre renseigné pour application de bureau
OAuth2Params..ClientSecret = gsO365_ClientSecret

OAuth2Params..ParamètresSupplémentaires = "force_reapprove=false"
//Ajouter user.read dans "API autorises" pour lire les informations de l'utilisateur connecté
OAuth2Params..Scope = "offline_access User.Read"

MonToken est un AuthToken = AuthIdentifie(OAuth2Params)

SI MonToken.Valide = Faux ALORS
Trace("/" + MonToken.Valeur + "/")
Trace("La connexion a échouée"+RC+MonToken.RéponseServeur)
SINON
Trace("ok")

FIN


Une idée ?
Registered member
15 messages
Posted on August, 23 2022 - 3:53 PM
C'est la partie facile, cf https://forum.pcsoft.fr/fr-FR/pcsoft.fr.windev/259053-envoi-mail-smtp-avec-oauth2-azure-259079/read.awp…
Par contre l'envoi de mail c'est une autre affaire : Microsoft est incapable de m'aider depuis 1 semaine.