IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Delphi ProSanteConnect OpenID Connect


Sujet :

Delphi

  1. #1
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut Delphi ProSanteConnect OpenID Connect
    Bonjour,
    je tente de réaliser une connexion au système Prosante Connect qui comme son grand frère France Connect est basé sur OpenId Connect en Delphi mais je n'y parviens pas...
    J'ai essayé plusieurs choses comme via indy ou avec les composants Rest mais rien ne marche...

    La meileure réponse que j'ai eu est celle-ci:
    HTTP Response : Not Found (404)
    <html><head></head><body><p style="font-size: 40px; font-weight: bold;">Sorry, we don't have any ressource about this</p></body></html>
    voici mon dernier code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      Source: TStringStream;
      ReponseContent: TStringStream;
      ClientID, ClientSecret, Token, RedirectUri, Scope: string;
    begin
      Memo1.Lines.Clear;
     
      ClientID    := 'monclientId';
      ClientSecret:= 'monsecretestbiengarde';
      RedirectUri := 'https://AdresseDemonSitePerso.fr';
      Scope       := 'openid';
     
      RESTClient.BaseURL := 'https://wallet.bas.psc.esante.gouv.fr/';
      try
        RESTRequest.Method := TRESTRequestMethod.rmPOST;
        RESTRequest.Resource := 'auth/realms/esante-wallet/protocol/openid-connect/token';
     
        RESTRequest.Params.AddItem('grant_type', 'client_credentials', TRESTRequestParameterKind.pkGETorPOST);
        RESTRequest.Params.AddItem('response_type', 'token', TRESTRequestParameterKind.pkGETorPOST);
     
        RESTRequest.Params.AddItem('client_id', ClientID, TRESTRequestParameterKind.pkGETorPOST);
        RESTRequest.Params.AddItem('client_secret', ClientSecret, TRESTRequestParameterKind.pkGETorPOST);
        RESTRequest.AddParameter('redirect_uri', RedirectUri, TRESTRequestParameterKind.pkGETorPOST);
        RESTRequest.Params.AddItem('scope', Scope, TRESTRequestParameterKind.pkGETorPOST);
     
        RESTRequest.Execute;
     
        if RESTRequest.Response.StatusCode = 200 then
        begin
          if RESTRequest.Response.GetSimpleValue('access_token', Token) then
          begin
            Memo1.Lines.add('access_token');
            Memo1.Lines.add(Token);
          end;
        end
        else
        begin
            Memo1.Lines.add(Format('HTTP Response : %s (%d)', [RESTRequest.Response.StatusText, RESTRequest.Response.StatusCode]));
            Memo1.Lines.add(RESTRequest.Response.Content);
        end;
      except
        on E: Exception do
          Memo1.Lines.add('General Error ' +  E.Message);
        on EHTTP: EHTTPProtocolException do
          Memo1.Lines.add('HTTP Error ' +  EHTTP.Message);
        on EREST: ERESTException do
          Memo1.Lines.add('REST Error ' +  EREST.Message);
      end;
    end;
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 460
    Points : 24 874
    Points
    24 874
    Par défaut
    ClientCredentials c'est bien https://auth.bas.psc.esante.gouv.fr/...-connect/token
    As-tu essayé en deux avec consentement (cherche la WebAuthForm dans Delphi) pour obtenir le Auth pour ensuite le transformer et jeton https://auth.bas.psc.esante.gouv.fr/.../ext/ciba/auth

    Note une différence selon cette documentation https://industriels.esante.gouv.fr/p...e-connect/ciba
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    https://wallet.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/token
    https://auth.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/token
    Mauvaise URL donc 404

    Ensuite les API CPS sont sur https://wallet.bas.psc.esante.gouv.fr et tu vas fournir le token en header bearer
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    Bonjour et merci de ton intérêt,

    J'ai testé mais pas vraiment mieux que ce soit avec auth ou wallet, je ne comprends pas tout...
    Mais j'ai fais évoluer mon code et y ajoutant l paramètre de query "acr_values", obligatoire qui me manquaient et maintenant j'ai bien un code 200 en response mais je ne suis pas certain de la suite:
    en effet dans les 2 cas j'ai une page web retournée mais je ne sais quoi en faire...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    Procedure TForm1.AuthenticateWithOpenIDConnect2(ClientID, ClientSecret, RedirectUri : String);
    var
      Source: TStringStream;
      ReponseContent: TStringStream;
      s, Token, Scope, State, ResponseType,
        AcrValues, Nonce: string;
      Guid : TGuid;
    begin
      Memo1.Lines.Clear;
     
      Scope       := 'openid scope_all';
      ResponseType:= 'code';
      AcrValues   := 'eidas1';
      State       := GuidToString(Guid); //a vérifier en retour d'appel pour la sécurité et éviter les attaques CSRF
      Nonce       := GuidToString(Guid); //a vérifier en retour du Token pour la sécurité et éviter les attaques de Rejeu
     
      RESTClient.BaseURL := 'https://wallet.bas.psc.esante.gouv.fr/';
      //RESTClient.BaseURL := 'https://auth.bas.psc.esante.gouv.fr/';
      try
        RESTRequest.Method := TRESTRequestMethod.rmPOST;
        RESTRequest.Resource := 'auth';   //??????
     
        RESTRequest.Params.AddItem('grant_type'   , 'client_credentials', pkGETorPOST);
        RESTRequest.Params.AddItem('response_type', ResponseType        , pkGETorPOST);
        RESTRequest.Params.AddItem('client_id'    , ClientID            , pkGETorPOST);
        RESTRequest.Params.AddItem('client_secret', ClientSecret        , pkGETorPOST);
        RESTRequest.Params.AddItem('redirect_uri' , RedirectUri         , pkGETorPOST);
        RESTRequest.Params.AddItem('scope'        , Scope               , pkGETorPOST);
        RESTRequest.Params.AddItem('acr_values'   , AcrValues           , pkGETorPOST);
        RESTRequest.Params.AddItem('state'        , State               , pkGETorPOST);
        RESTRequest.Params.AddItem('nonce'        , Nonce               , pkGETorPOST);
     
        Edit1.Text := RestRequest.GetFullRequestURL;
        RESTRequest.Execute;
     
        if RESTRequest.Response.StatusCode = 200 then
        begin
          {if RESTRequest.Response.GetSimpleValue('state', s) or (s <> State) then
            Memo1.Lines.add('Erreur lors de la vérification du state de la réponse qui ne correspond pas à celui de l''appel!')
          else} if RESTRequest.Response.GetSimpleValue('access_token', Token) then
          begin
            Memo1.Lines.add('access_token');
            Memo1.Lines.add(Token);
          end
          else
          begin
            Memo1.Lines.Text := RESTRequest.Response.Content;
     
            Memo1.Lines.SaveToFile('c:\temp\psc.html');
            webbrowser1.Navigate('c:\temp\psc.html');
          end;
        end
        else
        begin
            Memo1.Lines.add(Format('HTTP Response : %s (%d)', [RESTRequest.Response.StatusText, RESTRequest.Response.StatusCode]));
            Memo1.Lines.add(RESTRequest.Response.Content);
        end;
      except
        on E: Exception do
          Memo1.Lines.add('General Error ' +  E.Message);
        on EHTTP: EHTTPProtocolException do
          Memo1.Lines.add('HTTP Error ' +  EHTTP.Message);
        on EREST: ERESTException do
          Memo1.Lines.add('REST Error ' +  EREST.Message);
      end;
    end;
    Dans le cas ou je mets wallet j'obtiens en response:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    <!DOCTYPE html><html lang="fr"><head><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
      <meta charset="utf-8">
      <title>Authentification - Portail Pro Santé Connect</title>
      <base href="/auth/">	
     
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta name="google" content="notranslate">
      <link rel="icon" type="image/x-icon" href="favicon.ico">
      <style type="text/css">@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;font-display:block;src:url(<a href="https://fonts.gstatic.com/s/materialicons/v140/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2" target="_blank">https://fonts.gstatic.com/s/material...NcIhQ8tQ.woff2</a>) format('woff2');}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased;}</style>
    <style>@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, .15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff}*,:after,:before{-webkit-box-sizing:border-box;box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-family:var(--bs-body-font-family);font-size:1rem;font-size:var(--bs-body-font-size);font-weight:400;font-weight:var(--bs-body-font-weight);line-height:1.5;line-height:var(--bs-body-line-height);color:#212529;color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:#fff;background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@-webkit-keyframes placeholder-wave{to{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}:root{--esan-success-color:#72b375;--esan-danger-color:#db1729;--esan-primary-color:#084870;--esan-primary-fg-color:#FFF;--esan-primary-color-lighter:#1B70B7;--esan-border-color:#b6c0d0;--esan-text-color:#5a5151;--esan-text-color-lighter:#909090;--esan-danger-text-color:#E0212D;--esan-title-color:var(--esan-primary-color);--esan-success-text-color:var(--esan-success-color);--esan-form-label-color:#b6c0d0;--esan-disabled:#6c6d6e;--esan-btn-primary-bg-color:var(--esan-primary-color-lighter);--esan-btn-primary-fg-color:var(--esan-primary-fg-color);--esan-btn-hover-primary-bg-color:#29383C;--esan-btn-disabled-primary-bg-color:var(--esan-disabled);--esan-chkb-primary-bg-color:var(--esan-primary-color-lighter);--esan-chkb-primary-fg-color:var(--esan-primary-fg-color);--esan-chkb-mat-ripple-color:rgba(27, 142, 241, .4);--esan-link-primary-color:var(--esan-primary-color-lighter);--esan-link-hover-primary-color:var(--esan-primary-color);--esan-input-border-active-color:#6F6F6F;--esan-input-border-color:var(--esan-border-color);--esan-input-bg-color:#FFF;--esan-input-text-fg-color:#6F6F6F;--esan-input-text-bg-color:var(--esan-input-bg-color);--esan-input-text-placeholder-fg-color:#6f6f6f;--esan-input-text-border-color:var(--esan-input-border-color);--esan-input-text-border-active-color:var(--esan-input-border-active-color);--esan-frame-background-color:#f5f5f5;--esan-frame-shadow-color:#bdbdbd;--esan-header-background-color:#FFF;--esan-tab-header-bg-color:var(--esan-header-background-color);--esan-tab-header-fg-color:var(--esan-disabled);--esan-tab-content-bg-color:#f8f9fd;--esan-spinner-container-bg-color:var(--esan-primary-color);--esan-body-content-background-color:#ededed;--esan-body-html-background-color:var(--esan-primary-color);--esan-popup-header-bg-color:var(--esan-header-background-color);--esan-popup-content-bg-color:var(--esan-tab-content-bg-color);--esan-popup-footer-bg-color:var(--esan-primary-color)}html,body{width:100%;height:100%}body{font-family:Roboto,Helvetica Neue,sans-serif;font-weight:300;background-color:var(--esan-body-html-background-color);padding:1.5rem 0}@font-face{font-family:Roboto;font-weight:100;font-style:normal;src:url(Roboto-Thin.a34eab714d38dc03.ttf) format("truetype")}@font-face{font-family:Roboto;font-weight:300;font-style:normal;src:url(Roboto-Light.6d2d51951f189f7f.ttf) format("truetype")}@font-face{font-family:Roboto;font-weight:400;font-style:normal;src:url(Roboto-Regular.6d220b904eef61e1.ttf) format("truetype")}@font-face{font-family:Roboto;font-weight:500;font-style:normal;src:url(Roboto-Medium.50e73d0c201f239d.ttf) format("truetype")}@font-face{font-family:Roboto;font-weight:700;font-style:normal;src:url(Roboto-Bold.d3fa0b1aa729a89c.ttf) format("truetype")}@font-face{font-family:Roboto;font-weight:900;font-style:normal;src:url(Roboto-Black.73a54a4be47c9f53.ttf) format("truetype")}</style><link rel="stylesheet" href="styles.6e84055539324d13.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.6e84055539324d13.css"></noscript></head>
    <body>
      <app-root></app-root>
    <script src="runtime.cb88784eb7589798.js" type="module"></script><script src="polyfills.3d319b563aa4cf3f.js" type="module"></script><script src="scripts.4f8aa1b1174d809a.js" defer></script><script src="main.7e13d563a5b62fe0.js" type="module"></script>
     
    </body></html>

    Dans le cas où je mets auth j'obtiens la page:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    <!--
      ~ JBoss, Home of Professional Open Source.
      ~ Copyright (c) 2011, Red Hat, Inc., and individual contributors
      ~ as indicated by the @author tags. See the copyright.txt file in the
      ~ distribution for a full listing of individual contributors.
      ~
      ~ This is free software; you can redistribute it and/or modify it
      ~ under the terms of the GNU Lesser General Public License as
      ~ published by the Free Software Foundation; either version 2.1 of
      ~ the License, or (at your option) any later version.
      ~
      ~ This software is distributed in the hope that it will be useful,
      ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
      ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      ~ Lesser General Public License for more details.
      ~
      ~ You should have received a copy of the GNU Lesser General Public
      ~ License along with this software; if not, write to the Free
      ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
      ~ 02110-1301 USA, or see the FSF site: <a href="http://www.fsf.org" target="_blank">http://www.fsf.org</a>.
      -->
    <!DOCTYPE html>
     
    <html>
    <head>
        <title>Welcome to Keycloak</title>
     
        <meta charset="utf-8">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="robots" content="noindex, nofollow">
     
        <link rel="shortcut icon" href="resources/t6lev/welcome/keycloak/img/favicon.ico" />
     
                <link href="resources/t6lev/common/keycloak/node_modules/patternfly/dist/css/patternfly.css" rel="stylesheet" />
                <link href="resources/t6lev/common/keycloak/node_modules/patternfly/dist/css/patternfly-additions.css" rel="stylesheet" />
                <link href="resources/t6lev/welcome/keycloak/css/welcome.css" rel="stylesheet" />
     
                                  <script>!function(a){var e="https://s.go-mpulse.net/boomerang/",t="addEventListener";if("False"=="True")a.BOOMR_config=a.BOOMR_config||{},a.BOOMR_config.PageParams=a.BOOMR_config.PageParams||{},a.BOOMR_config.PageParams.pci=!0,e="https://s2.go-mpulse.net/boomerang/";if(window.BOOMR_API_key="VH5YX-W3RL4-8R4FH-GV7NG-E4YRG",function(){function n(e){a.BOOMR_onload=e&&e.timeStamp||(new Date).getTime()}if(!a.BOOMR||!a.BOOMR.version&&!a.BOOMR.snippetExecuted){a.BOOMR=a.BOOMR||{},a.BOOMR.snippetExecuted=!0;var i,_,o,r=document.createElement("iframe");if(a[t])a[t]("load",n,!1);else if(a.attachEvent)a.attachEvent("onload",n);r.src="javascript:void(0)",r.title="",r.role="presentation",(r.frameElement||r).style.cssText="width:0;height:0;border:0;display:none;",o=document.getElementsByTagName("script")[0],o.parentNode.insertBefore(r,o);try{_=r.contentWindow.document}catch(O){i=document.domain,r.src="javascript:var d=document.open();d.domain='"+i+"';void(0);",_=r.contentWindow.document}_.open()._l=function(){var a=this.createElement("script");if(i)this.domain=i;a.id="boomr-if-as",a.src=e+"VH5YX-W3RL4-8R4FH-GV7NG-E4YRG",BOOMR_lstart=(new Date).getTime(),this.body.appendChild(a)},_.write("<bo"+'dy onload="document._l();">'),_.close()}}(),"".length>0)if(a&&"performance"in a&&a.performance&&"function"==typeof a.performance.setResourceTimingBufferSize)a.performance.setResourceTimingBufferSize();!function(){if(BOOMR=a.BOOMR||{},BOOMR.plugins=BOOMR.plugins||{},!BOOMR.plugins.AK){var e=""=="true"?1:0,t="",n="jvf6iddachas6zfgzzha-f-e040e4c82-clientnsv4-s.akamaihd.net",i="false"=="true"?2:1,_={"ak.v":"36","ak.cp":"1312512","ak.ai":parseInt("787838",10),"ak.ol":"0","ak.cr":37,"ak.ipv":4,"ak.proto":"http/1.1","ak.rid":"cb34bfa","ak.r":42384,"ak.a2":e,"ak.m":"dscb","ak.n":"essl","ak.bpcip":"77.75.228.0","ak.cport":36727,"ak.gh":"96.17.104.47","ak.quicv":"","ak.tlsv":"tls1.2","ak.0rtt":"","ak.csrc":"-","ak.acc":"reno","ak.t":"1688653390","ak.ak":"hOBiQwZUYzCg5VSAfCLimQ==N/UqVhn3oC1zlKgwcei9R9pHj9XUO+sVZDUAtTC4u+tmH6SfsFF9sOu62Fv45J46p/Mr7q2r0dvWydkeiYHAddL0bthG5QyuRMiArjFHmvlSdYviDmBMaKYfpE8dMapU64XbX+Ohlvldcn2d5lBURpwCUhooEfT2RvT/JGsT10S3el7pcVy3xex2ROocqKT+YfjQV+BDKPwrchrcBuKLrA85Bx3amFoC7ZneaTUBinGVXieKQbfgQht/DUpNW0yohw9+kxl0fQWbWLkTf9EoqUI3YyQZZ3EdCZLQ7htf9ti3l627c7ePeVHER3lY4vcL2imqUlDfqDQIUWO9gXxM/EHrZmfZ9sT5HlHc3mIlFVYx8VSb7B8+C1M9gd6qAD8VXi2zUSkK8XffyxZ1Ug+6OB2kw50E1OSVGqybEVFyxik=","ak.pv":"2","ak.dpoabenc":"","ak.tf":i};if(""!==t)_["ak.ruds"]=t;var o={i:!1,av:function(e){var t="http.initiator";if(e&&(!e[t]||"spa_hard"===e[t]))_["ak.feo"]=void 0!==a.aFeoApplied?1:0,BOOMR.addVar(_)},rv:function(){var a=["ak.bpcip","ak.cport","ak.cr","ak.csrc","ak.gh","ak.ipv","ak.m","ak.n","ak.ol","ak.proto","ak.quicv","ak.tlsv","ak.0rtt","ak.r","ak.acc","ak.t","ak.tf"];BOOMR.removeVar(a)}};BOOMR.plugins.AK={akVars:_,akDNSPreFetchDomain:n,init:function(){if(!o.i){var a=BOOMR.subscribe;a("before_beacon",o.av,null,null),a("onbeacon",o.rv,null,null),o.i=!0}return this},is_complete:function(){return!0}}}}()}(window);</script></head>
     
    <body>
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2">
          <div class="welcome-header">
            <img src="resources/t6lev/welcome/keycloak/logo.png" alt="Keycloak" border="0" />
            <h1>Welcome to <strong>Keycloak</strong></h1>
          </div>
          <div class="row">
            <div class="col-xs-12 col-sm-4">
              <div class="card-pf h-l">
     
                <div class="welcome-primary-link">
                  <h3><a href="https://auth.bas.psc.esante.gouv.fr/auth/admin/"><img src="welcome-content/user.png">Administration Console <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
                  <div class="description">
                    Centrally manage all aspects of the Keycloak server
                  </div>
                </div>
              </div>
            </div>
            <div class="col-xs-12 col-sm-4">
              <div class="card-pf h-l">
                <h3><a href="https://www.keycloak.org/documentation.html"><img class="doc-img" src="welcome-content/admin-console.png">Documentation <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
                <div class="description">
     
                  User Guide, Admin REST API and Javadocs
     
                </div>
              </div>
            </div>
            <div class="col-xs-12 col-sm-4">
              <div class="card-pf h-m">
                <h3><a href="http://www.keycloak.org"><img src="welcome-content/keycloak-project.png">Keycloak Project <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
              </div>
              <div class="card-pf h-m">
                <h3><a href="https://groups.google.com/forum/#!forum/keycloak-user"><img src="welcome-content/mail.png">Mailing List <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
              </div>
              <div class="card-pf h-m">
                <h3><a href="https://issues.jboss.org/browse/KEYCLOAK"><img src="welcome-content/bug.png">Report an issue <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
              </div>
            </div>
          </div>
          <div class='footer'>
            <a href="http://www.jboss.org"><img src="welcome-content/jboss_community.png" alt="JBoss and JBoss Community"></a>
          </div>
        </div>
      </div>
    </div>
    </body>
    </html>
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 460
    Points : 24 874
    Points
    24 874
    Par défaut
    acr_values c'est une extension du OAuth, je ne sais pas trop à quoi cela sert, ce n'est pas pour forcer une entité de confirmation d'identité genre l'application MFA à utiliser ?


    Et attention auth c'est pour le mode avec IHM pour un utilisateur avec un écran de consentement
    le scénario c'est "/auth" qui retourne une page pour un WebBrowser (utilise REST.Authenticator.OAuth.WebForm.Win.Tfrm_OAuthWebForm), cela fini par faire une redirection te fournissant le code, ce code tu le passes en suite à "/token"
    et là entre en compte le MFA


    Si tu es en client_credentials, tu DOIS utiliser "/token" uniquement
    Et il n'y a pas de MFA


    Je n'ai bossé que sur Azure AD pour le OAuth, j'ai implémente AuthCode, client_credentials et ROPC
    et il y a plus de dix sur un Server Web en Symfony (j'avais XE2 et faire du Bearer Auth à l'époque c'était tout à la main, ROPC uniquement)

    dans un projet de Test j'ai


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function TForm1.GetAuthCode(AAuthenticator: TSLTOAuth2Authenticator): string;
    begin
      with TAuthCodeForm.Create() do
      try
        Navigate(AAuthenticator.GetAuthCodeRequestURL(), AAuthenticator.RedirectionEndpoint, Result);
      finally
        Free();
      end;
    end;
    AAuthenticator c'est une classe maison qui encapsule ce bazar (dont REST.Authenticator.OAuth.TOAuth2Authenticator) avec GetAuthCodeRequestURL() qui fournir une version largement amélioré par rapport à AuthorizationRequestURI()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //------------------------------------------------------------------------------
    function TSLTOAuth2AuthenticatorAzure.GetAuthCodeRequestURL(const AState: string): string;
    begin
      // https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code
      with TSLTOAuth2AuthenticatorAzure.TURLBuilder.Create() do
      try
        AddParam('client_id', FOwner.ClientID);
        if FOwner.ClientSecret <> '' then
          AddParam('client_secret', FOwner.ClientSecret);
        AddParam('response_type', 'code');
        AddParam('redirect_uri', FOwner.Context.RedirectionEndpoint);
        AddParam('scope', FOwner.Scope);
        AddParam('response_mode', 'query');
        if FOwner.Context.UserName <> ''  then
          AddParam('login_hint', FOwner.Context.UserName);
        AddParam('prompt', 'consent');
        if AState <> ''  then
          AddParam('state', AState);
     
        Result := BuildURL(FAuthorizeEndpoint);
      finally
        Free();
      end;
    end;
    et comme le OAuth est un standard pas toujours standard par exemple sur le offline, j'ai aussi une TSLTOAuth2AuthenticatorYahoo et TSLTOAuth2AuthenticatorGoogle qui gère les quelques variations de l'URL d'autorisation

    TAuthCodeForm c'est aussi une classe maison qui encapsule Tfrm_OAuthWebForm qui est utile surtout pour les Tests et la mise en place, sur un serveur, tu dois ajouter un client web pour assurer la redirection (Server REST Delphi, là où je suis c'est une architcure N Tiers plus cimplexe, Delphi c'est des BackEnd utilisé par le MiddleWare, lui même seul point d'entrée du FrontEnd Web)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    type
      TAuthCodeForm = class(TObject)
      private
        FExpectedRedictionURI: string;
        FLastErrorMessage: string;
        FWebForm: Tfrm_OAuthWebForm;
        FAuthCode: string;
        procedure AfterRedirectEventHandler(const AURL: string; var DoCloseWebView: Boolean);
      public
        function Navigate(const AURL: string; const AExpectedRedictionURI: string; out AAuthCode: string): Boolean;
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
     
    { TAuthCodeForm }
     
    //------------------------------------------------------------------------------
    function TAuthCodeForm.Navigate(const AURL: string; const AExpectedRedictionURI: string; out AAuthCode: string): Boolean;
     
      procedure CheckWebBrowserEmulation();
      const
        KEY = 'Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION';
      var
        Reg: TRegistry;
        EmulationLevel: Integer;
      begin
        EmulationLevel := 0;
     
        Reg := TRegistry.Create(KEY_QUERY_VALUE);
        try
          Reg.RootKey := HKEY_CURRENT_USER;
          if Reg.OpenKey(KEY, False) then
            if Reg.ValueExists(ExtractFileName(Application.ExeName)) then
              EmulationLevel := Reg.ReadInteger(ExtractFileName(Application.ExeName))
        finally
          Reg.Free();
        end;
     
        if EmulationLevel <> 11000 then
        begin
          if MessageDlg(Format('Allow Change WebBrowser Emulation Level from %d to 11000 ?', [EmulationLevel]), mtConfirmation, mbYesNo, 0) = mrYes then
          begin
            Reg := TRegistry.Create(KEY_SET_VALUE);
            try
              Reg.RootKey := HKEY_CURRENT_USER;
              if Reg.OpenKey(KEY, True) then
              begin
                Reg.WriteInteger(ExtractFileName(Application.ExeName), 11000);
                CheckOSError(Reg.LastError);
              end
              else
                CheckOSError(Reg.LastError);
            finally
              Reg.Free();
            end;
          end;
        end;
      end;
     
    begin
      FLastErrorMessage := '';
      FExpectedRedictionURI := AExpectedRedictionURI;
     
      CheckWebBrowserEmulation();
     
      FWebForm := Tfrm_OAuthWebForm.Create(nil);
      with FWebForm do
      try
        OnAfterRedirect := AfterRedirectEventHandler;
     
        ShowModalWithURL(AURL);
     
        Result := LastURL.StartsWith(AExpectedRedictionURI, True);
        if Result then
          AAuthCode := FAuthCode;
      finally
        FreeAndNil(FWebForm);
      end;
    end;
     
    //------------------------------------------------------------------------------
    procedure TAuthCodeForm.AfterRedirectEventHandler(const AURL: string; var DoCloseWebView: Boolean);
     
      function ExtractParam(const AParamName: string; out AParamValue: string): Boolean;
      var
        Icb, Ice: Integer;
      begin
        Icb := AURL.IndexOf(AParamName + '=');
        if Icb >= 0 then
        begin
          Icb := Icb + Length(AParamName) + 1;
     
          Ice := AURL.IndexOf('&', Icb);
          if Ice > Icb then
            AParamValue := AURL.Substring(Icb, Ice - Icb)
          else
            AParamValue := AURL.Substring(Icb);
     
          Exit(True);
        end;
     
        AParamValue := '';
        Result := False;
      end;
     
      function ExtractCode(): Boolean;
      begin
        Result := ExtractParam('code', FAuthCode);
      end;
     
      procedure ShowError();
      var
        Error, ErrorSubCode, ErrorDescription, ErrorURI: string;
      begin
        if ExtractParam('error', Error) then
        begin
          Error := System.NetEncoding.TURLEncoding.URL.Decode(Error);
          FLastErrorMessage := 'Error: ' + Error;
     
          FWebForm.Caption := Error;
        end;
     
        if ExtractParam('error_subcode', ErrorSubCode) then
        begin
          ErrorSubCode := System.NetEncoding.TURLEncoding.URL.Decode(ErrorSubCode);
          if FLastErrorMessage <> ''  then
            FLastErrorMessage := FLastErrorMessage + sLineBreak;
          FLastErrorMessage := FLastErrorMessage + 'Error Code: ' + ErrorSubCode;
     
          FWebForm.Caption := Error + ' ' + ErrorSubCode;
        end;
     
        if ExtractParam('error_description', ErrorDescription) then
        begin
          ErrorDescription := System.NetEncoding.TURLEncoding.URL.Decode(ErrorDescription);
          if FLastErrorMessage <> ''  then
            FLastErrorMessage := FLastErrorMessage + sLineBreak;
          FLastErrorMessage := FLastErrorMessage + 'Error Description: ' + ErrorDescription;
     
          FWebForm.Caption := ErrorDescription;
        end;
     
        if ExtractParam('error_uri', ErrorURI)  then
        begin
          ErrorURI := System.NetEncoding.TURLEncoding.URL.Decode(ErrorURI);
          if FLastErrorMessage <> ''  then
            FLastErrorMessage := FLastErrorMessage + sLineBreak;
          FLastErrorMessage := FLastErrorMessage + 'See Detail: ' + ErrorURI;
     
          FWebForm.Browser.Navigate(ErrorURI);
        end;
      end;
     
     
      procedure ExtractErrorFromBrowser();
     
        function TryGetJSONString(AJSONObject: TJSONObject; const PairName: string): string;
        var
          Value: TJSONValue;
        begin
          Value := AJSONObject.Values[PairName];
          if not Assigned(Value) or not Value.TryGetValue(Result)then
            Result := '';
        end;
     
      const
        JSON_START_MARK = '$Config=';
      var
        Stream: TStringStream;
        StreamIntf: IStream;
        JSONPos: Integer;
        Content: System.JSON.TJSONObject;
      begin
        // On crée un flux
        Stream := TStringStream.Create();
        try
          StreamIntf := TStreamAdapter.Create(Stream);
     
          (FWebForm.Browser.Document as IPersistStreamInit).Save(StreamIntf, False);
     
          JSONPos := Pos(JSON_START_MARK, Stream.DataString);
          if JSONPos > 0 then
          begin
            Stream.Position := JSONPos + Length(JSON_START_MARK) - 1;
     
            Content := System.JSON.TJSONObject.Create();
            try
              Content.Parse(Stream.Bytes, Stream.Position);
              FLastErrorMessage := System.NetEncoding.THTMLEncoding.HTML.Decode(TryGetJSONString(Content, 'strServiceExceptionMessage'));
            finally
              Content.Free();
            end;
          end;
        finally
          Stream.Free();
        end;
      end;
     
    begin
      if AURL.StartsWith(FExpectedRedictionURI, True) then
      begin
        if ExtractCode() then
          DoCloseWebView := True
        else
          ShowError();
      end
      else
        ExtractErrorFromBrowser();
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Salut, je gère l'authentification CIBA (PSC pour clients lourds), c'est ce que tu cherches à faire ?

    Est-ce que je peux te demander dans quel cadre tu travailles sur PSC ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    Bonjour j'ai en fait deux cas le premier en lourd donc oui cela m'intéresse, car malgré l'aide de @ShaiLeTroll la page que j'affiche avec les navigateurs edge ou ie dans delphi 11.3 reste blanche sans rien comme si ça ne lançait pas les .js de la page... alors que en faisant un shellexecute de mon url mon navigateur Edge prends la main et affiche bien la page.

    Mon deuxième cas sera via une pageweb dans Azure avec en backend mon delphi ou un nodejs et u lien à faire avec Azure-AD. tout un programme...
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    en fait je ne comprend pas le mélange, avec CIBA tu n'as pas besoin d'un navigateur...c'est tout l'intérêt de la chose d'ailleurs.

    1) tu fais un POST vers https://auth.bas.psc.esante.gouv.fr/.../ext/ciba/auth

    avec en paramètres
    scope=openid identity scope_all
    login_hint=<RPPS>
    binding_message=<99>
    acr_values=eidas1

    où <RPPS> et le numéro RPPS
    et <99> est un nombre aléatoire de 2 chiffres

    sans oublier un Content-Type: application/x-www-form-urlencoded; charset="utf-8"
    et une authentification: Basic Base64(client_id:secret)

    ça doit te donner une réponse JSON qui comprend un auth_req_id

    2) tu POST sur https://auth.bas.psc.esante.gouv.fr/...-connect/token
    grant_type=urn:openid:params:grant-type:ciba
    req_id=<auth_req_id>

    ce qui va te donner l'état authorization_pending voir slow_down, tant que l'utilisateur n'a pas fait son authentification sur mobile avec le code <99> envoyé

    puis tu reçois un access_token qui te permets d'interroger https://auth.bas.psc.esante.gouv.fr/...nnect/userinfo
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    j'ai deux environnements l'un en lourd et l'autre en cloud c'est pour ça.
    Mais je vais déjà tester via ciba
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  9. #9
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    Je pense que je n'ai pas dû bien comprendre car voici mon code suivant les indications CIBA et j'ai l'erreur : EHTTPProtocolException avec le message 'HTTP/1.1 500 Internal Server Error'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    procedure TForm1.Button5Click(Sender: TObject);
    var
      ClientID, ClientSecret,  authorizeUrl, Scope, AcrValues, login_hint, ResponseType: string;
    begin
      authorizeUrl := 'https://auth.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/ext/ciba/auth';
      ClientID     := TNetEncoding.Base64.Encode('xxxxxxxxxxxxxxxxxxxxx');
      ClientSecret := TNetEncoding.Base64.Encode('xxxxxxxxxxxxxxxxxxxxxxxxxxx');
      Scope       := 'openid identity scope_all';
      login_hint  := '1111111111111';
      AcrValues   := 'eidas1';
      ResponseType:= 'query';
     
     
      RESTClient.BaseURL := authorizeUrl;
     
      RESTRequest.Method := TRESTRequestMethod.rmPOST;
     
      RESTRequest.Params.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
     
     
      RESTRequest.Params.AddItem('grant_type'   , 'client_credentials', pkGETorPOST);
      RESTRequest.Params.AddItem('response_type', ResponseType        , pkGETorPOST);
      RESTRequest.Params.AddItem('client_id'    , ClientID            , pkGETorPOST);
      RESTRequest.Params.AddItem('client_secret', ClientSecret       , pkGETorPOST);
      RESTRequest.Params.AddItem('scope'        , Scope               , pkGETorPOST);
      RESTRequest.Params.AddItem('login_hint'   , login_hint          , pkGETorPOST);
      RESTRequest.Params.AddItem('acr_values'   , AcrValues           , pkGETorPOST);
     
      Edit1.Text := RestRequest.GetFullRequestURL(True);
      RESTRequest.Execute;
     
      if RESTRequest.Response.StatusCode = 200 then
      begin
        Memo1.Text := 'OK';
      end;
    end;
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    ajoute un HTTPBasicAuthenticator et modifie comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ClientID, ClientSecret,  authorizeUrl, Scope, AcrValues, login_hint, ResponseType: string;
    begin
      authorizeUrl := 'https://auth.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/ext/ciba/auth';
      ClientID     := 'xxxxxxxxxxxxxxxxxxxxx';
      ClientSecret := 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
      Scope       := 'openid identity scope_all';
      login_hint  := '1111111111111';
      AcrValues   := 'eidas1';
      ResponseType:= 'query';
     
     
      RESTClient.BaseURL := authorizeUrl;
     
      RESTRequest.Method := TRESTRequestMethod.rmPOST;
     
     
    //  RESTRequest.Params.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
      RESTClient.ContentType := 'application/x-www-form-urlencoded';
     
      HTTPBasicAuthenticator.Username := ClientID;
      HTTPBasicAuthenticator.Password := ClientSecret;
     
    //  RESTRequest.Params.AddItem('grant_type'   , 'client_credentials', pkGETorPOST);
    //  RESTRequest.Params.AddItem('response_type', ResponseType        , pkGETorPOST);
    //  RESTRequest.Params.AddItem('client_id'    , ClientID            , pkGETorPOST);
    //  RESTRequest.Params.AddItem('client_secret', ClientSecret       , pkGETorPOST);
      RESTRequest.Params.AddItem('scope'        , Scope               , pkGETorPOST);
      RESTRequest.Params.AddItem('login_hint'   , login_hint          , pkGETorPOST);
      RESTRequest.Params.AddItem('binding_message', '42', pkGETorPOST);
      RESTRequest.Params.AddItem('acr_values'   , AcrValues           , pkGETorPOST);
     
      Edit1.Text := RestRequest.GetFullRequestURL(True);
      RESTRequest.Execute;
     
      Memo1.Text := IntTostr( RESTRequest.Response.StatusCode);
      Memo1.Lines.Add(RESTRequest.Response.Content);
    end;
    j'ai mis en dur 42 pour le binding_message mais il faut générer un numéro aléatoire sur 2 chiffres.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    J'ai testé et comme j'avais une erreur j'ai remanié un peu mon code pour ne pas dépendre de mon dfm mais j'ai tjs la même erreur: EHTTPProtocolException avec le message 'HTTP/1.1 500 Internal Server Error......

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    procedure TForm1.Button5Click(Sender: TObject);
    var
      ClientID, ClientSecret,  authorizeUrl, Scope, AcrValues, login_hint: string;
      MyRestClient   : TRESTClient;
      MyRESTRequest  : TRESTRequest;
      MyHTTPBasicAuth: THTTPBasicAuthenticator;
    begin
      authorizeUrl  := 'https://auth.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/ext/ciba/auth';
      ClientID      := 'xxxxxxxxxxxxxxxxxxx';
      ClientSecret  := 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
      Scope         := 'openid identity scope_all';
      login_hint    := '8999xxxxxxxx';
      AcrValues     := 'eidas1';
     
      MyRestClient    := TRESTClient.Create(authorizeUrl);
      MyHTTPBasicAuth := THTTPBasicAuthenticator.Create(ClientID, ClientSecret);
      MyRESTRequest   := TRESTRequest.Create(nil);
      try
        MyRestClient.Authenticator := MyHTTPBasicAuth;
        MyRESTRequest.Client := MyRestClient;
     
        MyRESTRequest.Method := TRESTRequestMethod.rmPOST;
        MyRESTRequest.Params.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
     
        MyRESTRequest.Params.AddItem('scope'          , Scope       , pkGETorPOST);
        MyRESTRequest.Params.AddItem('login_hint'     , login_hint  , pkGETorPOST);
        MyRESTRequest.Params.AddItem('binding_message', '25'        , pkGETorPOST);
        MyRESTRequest.Params.AddItem('acr_values'   , AcrValues     , pkGETorPOST);
     
        //Edit1.Text := MyRESTRequest.GetFullRequestURL(True);
        MyRESTRequest.Execute;
     
        if MyRESTRequest.Response.StatusCode = 200 then
        begin
          Memo1.Text := 'OK';
        end;
      finally
        MyRESTRequest.Free;
        MyHTTPBasicAuth.Free;
        MyRestClient.Free;
      end;
    end;
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  12. #12
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //    MyRESTRequest.Params.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
        MyRESTClient.ContentType := 'application/x-www-form-urlencoded';
    EDIT: d'ailleurs il n'est pas même nécessaire de le préciser

    NB: les serveurs de l'ANS sont extrêmement tatillons, et la moindre erreur provoque généralement une erreur 500 qui ne donne donc aucune info puisque c'est juste un plantage de la requête au lieu de dire que tel champ est invalide par exemple.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    Haaaa merci effectivement ça marche, c'est très tatillon....
    Je passe à la suite et je reviens
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  14. #14
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    en fait je ne comprend pas le mélange, avec CIBA tu n'as pas besoin d'un navigateur...c'est tout l'intérêt de la chose d'ailleurs.

    1) tu fais un POST vers https://auth.bas.psc.esante.gouv.fr/.../ext/ciba/auth
    ...
    ça doit te donner une réponse JSON qui comprend un auth_req_id

    2) tu POST sur https://auth.bas.psc.esante.gouv.fr/...-connect/token
    grant_type=urn:openid:params:grant-type:ciba
    req_id=<auth_req_id>

    ce qui va te donner l'état authorization_pending voir slow_down, tant que l'utilisateur n'a pas fait son authentification sur mobile avec le code <99> envoyé

    puis tu reçois un access_token qui te permets d'interroger https://auth.bas.psc.esante.gouv.fr/...nnect/userinfo
    Alors j'ai bien le req_id que je lis dans le json ainsi que l'intervale et l'expire... mais lors que je poste vers https://auth.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/token
    en ajoutant le grant_type et le req_id reçu, j'ai l'erreur
    HTTP/1.1 400 Bad Request
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    function TProSanteConnect.GetTokenId(AuthReqID : String): String;
    begin
      try
        MyRestClient.BaseURL := TokenUrl;
        MyRESTRequest.Method := TRESTRequestMethod.rmPOST;
     
        MyRESTRequest.Params.AddItem('grant_type', uriEncode('urn:openid:params:grant-type:ciba'), pkGETorPOST);
        MyRESTRequest.Params.AddItem('req_id', uriEncode(AuthReqID), pkGETorPOST);
     
        MyRESTRequest.Execute;
     
        if MyRESTRequest.Response.StatusCode = 200 then
        begin
     
        end;
      Except
     
      end;
    end;
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  15. #15
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    le nom du paramètre c'est auth_req_id et pas req_id
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  16. #16
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    Oui c'est vrai, mauvais copier coller...
    Mais j'ai corrigé et toujours la même erreur.

    J'ai laissé les paramètres de la requête précédente cela perturbe peut-être le serveur?
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  17. #17
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    que je regarde...dans mon code j'ai un objet HTTP, je fixe l'authorization et le contentType au début et je n'y touche plus

    après la récupération de auth_req_id je boucle sur un POST vers /auth/realms/esante-wallet/protocol/openid-connect/token des deux paramètres ci-dessus jusqu'à obtenir un 200 (entre deux tu as des messages pending ou slow down), du coup je Sleep() en fonction de l'interval retourné précédemment.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      {
      "error":"authorization_pending",
      "error_description":"The authorization request is still pending as the end-user hasn't yet been authenticated."
      }
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  18. #18
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    j'ai tenté de le faire en une seule fonction mais pas mieux...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    function TProSanteConnect.GetAuthentCiba: String;
    var
      jO : TJSONObject;
      AuthReqID : String;
    begin
      try
        MyRestClient.BaseURL := AuthorizeUrl;
     
        MyRESTRequest.Method := TRESTRequestMethod.rmPOST;
     
        //MyRESTRequest.Params.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
        MyRESTClient.ContentType := 'application/x-www-form-urlencoded';
        MyRESTRequest.Params.AddItem('scope'          , 'openid identity scope_all' , pkGETorPOST);
        MyRESTRequest.Params.AddItem('login_hint'     , NumRpps       , pkGETorPOST);
        MyRESTRequest.Params.AddItem('binding_message', BindingMessage, pkGETorPOST);
        MyRESTRequest.Params.AddItem('acr_values'     , 'eidas1'      , pkGETorPOST);
     
        MyRESTRequest.Execute;
     
        if MyRESTRequest.Response.StatusCode = 200 then
        begin
          Result := MyRESTRequest.Response.Content;
     
          jO := TJSONObject.ParseJSONValue(Result) as TJSONObject;
          jO.TryGetValue<string>('auth_req_id', AuthReqID);
          if not AuthReqID.IsEmpty then
          begin
            MyRestClient.BaseURL := TokenUrl;
            MyRESTRequest.Params.AddItem('grant_type', uriEncode('urn:openid:params:grant-type:ciba'), pkGETorPOST);
            MyRESTRequest.Params.AddItem('auth_req_id', uriEncode(AuthReqID), pkGETorPOST);
            MyRESTRequest.Execute;
          end;
        end;
      Except
     
      end;
    end;
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

  19. #19
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    les paramètres sont encodés automatiquement

    j'ai insérer ton code dans mon précédent test

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
        if MyRESTRequest.Response.StatusCode = 200 then
        begin
          jO := TJSONObject.ParseJSONValue(MyRESTRequest.Response.Content) as TJSONObject;
          jO.TryGetValue<string>('auth_req_id', AuthReqID);
          if not AuthReqID.IsEmpty then
          begin
            MyRestClient.BaseURL := 'https://auth.bas.psc.esante.gouv.fr/auth/realms/esante-wallet/protocol/openid-connect/token';
            MyRESTRequest.Params.AddItem('grant_type', 'urn:openid:params:grant-type:ciba', pkGETorPOST);
            MyRESTRequest.Params.AddItem('auth_req_id', AuthReqID, pkGETorPOST);
            MyRESTRequest.Execute;
          end;
        end;
     
        Memo1.Text := IntTostr( MyRESTRequest.Response.StatusCode);
        Memo1.Lines.Add(MyRESTRequest.Response.Content);
        (*
        400
        {"error":"authorization_pending","error_description":"The authorization request is still pending as the end-user hasn't yet been authenticated."}
        *)
    j'ai bien une erreur 400 qui sera là tant que l'utilisateur n'aura pas validé
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  20. #20
    Membre confirmé
    Avatar de korntex5
    Homme Profil pro
    Directeur technique
    Inscrit en
    Juin 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 414
    Points : 454
    Points
    454
    Billets dans le blog
    1
    Par défaut
    moi j'ai

    (*
    400
    {"error":"unsupported_grant_type","error_description":"Unsupported grant_type"}
    *)

    Mais j'ai fini par trouver j'ai voulu faire trop bien en ajoutant les uriEncode alors que c'est géré en natif des fonctions...Maintenant cela répond correctement, je passe à l'étape 3 les infos user
    Que la source soit avec moi!
    Jérôme JEAN-MARAULT

Discussions similaires

  1. [Débutant] Récupération d'un token avec OpenID Connect en C#
    Par magneto35 dans le forum ASP.NET MVC
    Réponses: 0
    Dernier message: 23/04/2019, 10h22
  2. Appli Delphi - Objet DCOM - Connection serveur 2003
    Par antoinefefe dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 15/05/2013, 12h20
  3. Serveur Delphi | Client Java | Connection refused
    Par tiboudchou dans le forum Services Web
    Réponses: 3
    Dernier message: 06/10/2008, 16h36
  4. [mysql] Connection delphi à mysql
    Par pataluc dans le forum Bases de données
    Réponses: 3
    Dernier message: 24/06/2004, 16h37
  5. [Mysql] Connection delphi à une bdd sous easyphp...
    Par pataluc dans le forum Bases de données
    Réponses: 2
    Dernier message: 14/06/2004, 09h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo