I would like to call a secured web service with Uniface. To do this, I first have to call up an access token in ADFS (Active Directory Federation Services) using a user, a password and a ClientId for a client. Can anyone tell me how this is implemented in Uniface?
What I know:
HTTP address of the ADFS
ClientId of the web service
user
password
------------------------------
Viktor Künstler
Abrechnungszentrum Emmendingen
Emmendingen DE
------------------------------
Hello Viktor,
I have tried to creating something simular for a webservice call SomToday. I was able to get the access token. The project was and is still work in progress. Only I did not continue to complete the whole program. The following operations I used for handling the request of the access token. I hope it is self-explanatory and you get a good push in the right direction with this. (Sorry for the Dutch, it's a private project.)
Component "SOMTODAY"
  operation Inloggen   Logging in to the application, with some checking for refreshing the token
  operation getAuth  Handling the request for getting the token
  operation auth_refresh  Handling the request for refreshing the token
  Defines   The used defines 
Component "ST_WEBHANDLING"
  operation  send    Handling the request and response with the Uniface UHTTP component.
"SOMTODAY" operation Inloggen
;-----------------------------------------------------------------------------------------------------------
; Inloggen
;
; activate "SOMTODAY".Inloggen(school_uuidIN, leerling_nummerIN, wachtwoordIN, outParamsOUT)
;-----------------------------------------------------------------------------------------------------------
; Inloggen op SomToday. 
;
; parameters:
;    input:     school_uuid         Te verzenden bericht, het request
;               leerling_nummer     Login naam om te kunnen inloggen bij SomToday
;               wachtwoord          Wachtwoord behorende bij het leerling_nummer
;    output:    outParams           Lijst met output parameters, onder andere:
;                 message             Melding
;-----------------------------------------------------------------------------------------------------------
public operation Inloggen
params
  string    school_uuid      : IN
  string    leerling_nummer  : IN
  string    wachtwoord       : IN
  string    outParams        : OUT
endparams
  outParams = ""
  if (school_uuid = "" | leerling_nummer = "" | wachtwoord = ""  )
    $auth_time$ = 0
    $bError$ = <true>
    putitem/id outParams, "message", "fout inloggen, check je gegevens!"
    putmess "fout inloggen, check je gegevens!"
    return -1
  endif
putmess "tijdstip  : %%$datim%%%"
putmess "auth_time : %%$auth_time$%%%"
putmess "verschil  : %%(($datim - $auth_time$)*86400)%%%"
  if ($bError$ = <true> | (($datim - $auth_time$)*86400) > 3060)
;    if (school_uuid = "")
;      $auth_time$ = 0
;      putitem/id outParams, "message", "fout inloggen, check je gegevens!"
;      putmess "fout inloggen, check je gegevens!"
;    endif
    activate "%%$instancename%%%".getAuth(school_uuid, leerling_nummer, wachtwoord)
    if ($access_token$ = "")
      $auth_time$ = 0
      $bError$ = <true>
      putitem/id outParams, "message", "fout inloggen, check je gegevens!"
      putmess "fout inloggen, check je gegevens!"
      return -2
    endif
    $auth_time$ = $datim
    $bError$ = <false>
  elseif ($auth_time$ != 0.0 & (($datim - $auth_time$)*86400) > 3000)
    if ($refresh_token$ != "")
      activate "%%$instancename%%%".auth_refresh($refresh_token$)
      if ($refresh_token$ = "" | $bError$ = <true>)
        $bError$ = <true>
        putitem/id outParams, "message", "fout inloggen, check je gegevens!"
        putmess "fout inloggen, check je gegevens!"
        return -3
      endif
      $auth_time$ = $datim
	endif
  elseif ($bError$ = <true> | $auth_time$ = 0.0)
 ;   if (school_uuid = "")
 ;     $auth_time$ = 0
 ;     putitem/id outParams, "message", "fout inloggen, check je gegevens!"
 ;     putmess "fout inloggen, check je gegevens!"
 ;   endif
    activate "%%$instancename%%%".getAuth(leerling_nummer, wachtwoord, school_uuid)
    if ($access_token$ = "")
      $auth_time$ = 0
	  $bError$ = <true>
      putitem/id outParams, "message", "fout inloggen, check je gegevens!"
      putmess "fout inloggen, check je gegevens!"
      return -4
    endif
    $auth_time$ = $datim
    $bError$ = <false>
  endif
end  ;  operation Inloggen
Component "SOMTODAY" operation getAuth
operation getAuth
params
  string    school_uuid     : IN
  string    leerling_nummer : IN
  string    wachtwoord      : IN
endparams
variables
  string    sData
  struct    strData
  numeric   vn_status
  xmlstream vx_respons
  string    vl_http_params, vs_http_status, vl_http_header, vs_melding
endvariables
;https://somtoday.nl/oauth2/authorize
;?redirect_uri=somtodayleerling://oauth/callback
;&client_id=D50E0C06-32D1-4B41-A137-A9A850C892C2
;&response_type=code
;&prompt=login
;&scope=openid
;&code_challenge=tCqjy6FPb1kdOfvSa43D8a7j8FLDmKFCAz8EdRGdtQA
;&code_challenge_method=S256
;&tenant_uuid={TENANT_UUID}
;&oidc_iss={OIDC_ISS}".toString();
  sData = "https://inloggen.somtoday.nl/oauth2/authorize" 
  sData = $concat(sData, "?", "redirect_uri=", "somtodayleerling://oauth/callback")
  sData = $concat(sData, "&", "client_id=<client_id>")
  sData = $concat(sData, "&", "response_type=", "code")
  sData = $concat(sData, "&", "scope=", "openid")
  sData = $concat(sData, "&", "prompt=", "login")
  sData = $concat(sData, "&", "code_challenge=", "tCqjy6FPb1kdOfvSa43D8a7j8FLDmKFCAz8EdRGdtQA")
  sData = $concat(sData, "&", "code_challenge_method=", "S256")
  sData = $concat(sData, "&", "tenant_uuid=", "%%school_uuid%%%")
  sData = $concat(sData, "&", "oidc_iss=", "https://idpcluster.stichtingcarmelcollege.nl/nidp/oauth/nam")
  putitem/id vl_http_params, "URL", sData
  putitem/id vl_http_params, "CONTENTTYPE", "application/x-www-form-urlencoded"
  putitem/id vl_http_params, "CHARSET", "UTF-8"
  putitem/id vl_http_params, "TIMEOUT", 10000
  putitem/id vl_http_params, "HTTPS", 1
  ;putitem/id vl_http_params, "METHOD", "POST"
;  putitem/id vl_http_params, "URL", "<URL_base>/oauth2/token"
;  putitem/id vl_http_params, "CONTENTTYPE", "application/x-www-form-urlencoded"
;  putitem/id vl_http_params, "CHARSET", "UTF-8"
;  putitem/id vl_http_params, "TIMEOUT", 10000
;  putitem/id vl_http_params, "HTTPS", 1
;  putitem/id vl_http_params, "METHOD", "POST"
;
;  sData = "grant_type=password" 
;  sData = $concat(sData, "&", "username=", "%%school_uuid%%%\\%%leerling_nummer%%%")
;  sData = $concat(sData, "&", "password=", "%%wachtwoord%%%")
;  sData = $concat(sData, "&", "response_type=", "code")
;  sData = $concat(sData, "&", "scope=", "openid")
;  sData = $concat(sData, "&", "tenant_uuid=", "%%school_uuid%%%")
;  sData = $concat(sData, "&", "client_id=<client_id>")
;  sData = $concat(sData, "&", "redirect_uri=", "somtodayouder%3A%2F%2Foauth%2Fcallback")
;  sData = $concat(sData, "&", "session=", "no_session")
;  sData = $concat(sData, "&", "oidc_iss=", "https://idpcluster.stichtingcarmelcollege.nl/nidp/oauth/nam")
;; redirect_uri 	Query 	somtodayleerling://oauth/callback
;; client_id 	Query 	D50E0C06-32D1-4B41-A137-A9A850C892C2
;; response_type 	Query 	code
;; scope 	Query 	openid
;; tenant_uuid 	Query 	[SCHOOL UUID]
;; session 	Query 	no_session
;; state 	Query 	[RANDOM STATE]
;; code_challenge 	Query 	[CODE CHALLENGE]
;; code_challenge_method 	Query 	S256
putmess sData
  activate "ST_WEBHANDLING".send(sData, vl_http_params, vs_http_status, vl_http_header, vx_respons, vn_status, vs_melding)
; fileload "project\\auth.json", vx_respons
  putmess "HTTPSTATUS         : %%vs_http_status%%%"
  putmess "RESPONS            : %%vx_respons%%%"
  putmess "HTTPHEADER         : %%$item("REQUEST", vl_http_header)%%%"
  putmess "HTTPHEADER_RESPONS : %%$item("RESPONS", vl_http_header)%%%"
  jsonToStruct strData, vx_respons
  $access_token$ = strData->"access_token"
  $refresh_token$ = strData->"refresh_token"
  putitem/id $access_header$, "Authorization", "Bearer %%$access_token$%%%"
  putitem/id $access_header$, "Accept", "application/json"
  $somtoday_api_url$ = strData->"somtoday_api_url"
  $somtoday_tenant$ = strData->"somtoday_tenant"
  $id_token$ = strData->"id_token"
  $auth_expires_in$ = strData->"expires_in"
end  ;  operation getAuth
Component "SOMTODAY" operation auth_refresh
operation auth_refresh
params
  string    refresh_token  : IN
endparams
variables
  string    sData
  struct    strData
  numeric   vn_status
  xmlstream vx_respons
  string    vl_http_params, vs_http_status, vl_http_header, vs_melding
endvariables
  putitem/id vl_http_params, "URL", "<URL_base>/oauth2/token"
  putitem/id vl_http_params, "CONTENTTYPE", "application/x-www-form-urlencoded"
  putitem/id vl_http_params, "CHARSET", "UTF-8"
  putitem/id vl_http_params, "TIMEOUT", 10000
  putitem/id vl_http_params, "HTTPS", 1
  putitem/id vl_http_params, "METHOD", "POST"
  sData = "grant_type=refresh_token" 
  sData = $concat(sData, "&", "refresh_token=", "%%refresh_token%%%")
  sData = $concat(sData, "&", "client_id=<client_id>")
  activate "ST_WEBHANDLING".send(sData, vl_http_params, vs_http_status, vl_http_header, vx_respons, vn_status, vs_melding)
  putmess "HTTPSTATUS         : %%vs_http_status%%%"
  putmess "RESPONS            : %%vx_respons%%%"
  putmess "HTTPHEADER         : %%$item("REQUEST", vl_http_header)%%%"
  putmess "HTTPHEADER_RESPONS : %%$item("RESPONS", vl_http_header)%%%"
putmess vx_respons
  jsonToStruct strData, vx_respons
  putmess strData->$dbgString
  $access_token$ = strData->"access_token"
  $refresh_token$ = strData->"refresh_token"
  putitem/id $access_header$, "Authorization", "Bearer %%$access_token$%%%"
  putitem/id $access_header$, "Accept", "application/json"
  $somtoday_api_url$ = strData->"somtoday_api_url"
putmess $access_token$
putmess $refresh_token$
putmess $access_header$
putmess $somtoday_api_url$
end  ;  operation auth_refresh
Component "ST_WEBHANDLING" operation send
;-----------------------------------------------------------------------------------------------------------
; SEND
;
; activate send(requestIN, paramsIN, HTTPstatusOUT, HTTPheaderOUT, responsOUT, statusOUT, contextOUT)
;-----------------------------------------------------------------------------------------------------------
; Verzend een bericht via HTTP. 
;
; parameters:
;    input:     px_request          Te verzenden bericht, het request
;               pl_params           Params gecombineerd in een lijst. Waaronder:
;                 url                 Endpoint    
;                 https               Verzenden via HTTPS?
;                 timeout             Timeout van het verzonden bericht, leeg = geen timeout
;                 username            Username om van HTTP Authentication gebruik te maken
;                 password            Password behorende bij de username
;                 soapaction          De SOAPACTION in de httpheader
;                 contenttype         De contenttype in de httpheader
;                 charset             Charset van de request
;                 Authorization       Authorization
;                 Accept              Accept
;                 method              Gebruikte HTTP method (GET of POST)
;    output:    pn_http_status      HTTP status van de verzending, onder andere:
;                                        0 = bericht hoogst waarschijnlijk niet verzonden
;                                      200 = bericht is goed ontvangen door de wederpartij. Px_respons bevat antwoord.
;                                      404 = URL is niet correct, wederpartij niet gevonden
;                                      500 = Ontvanger heeft fout in bericht geconstateerd. Px_respons bevat fout.
;               pl_http_header      HTTP header
;               px_respons          Antwoord zoals ontvangen van de wederpartij.
;               pn_status           Status van de verwerking. Onder andere:
;                                        0 = Verwerking goed verlopen. HTTP status = 200!
;                                        1 = Verwerking goed verlopen. HTTP status geeft echter fout!!
;                                       -1 = onbekende fout bij verzending
;                                      -10 = URL niet goed 
;                                      -11 = Timeout
;                                      -12 = Timeout
;                                      -13 = Request niet goed
;               pl_status_context   Context van de status.
;-----------------------------------------------------------------------------------------------------------
public operation send
params
  xmlstream px_request :IN
  string    pl_params : IN
  numeric   pn_http_status : OUT
  string    pl_http_header : OUT
  xmlstream px_respons : OUT
  numeric   pn_status : OUT
  string    pl_status_context : OUT
endparams
variables
  string    vs_headers, strInstance, vs_respons_header, vs_url
  string    vs_username, vs_password, vs_contenttype, vs_soapaction
  string    vs_authorization, vs_accept
  string    vs_method, vl_http_header, vs_charset, v_tmp
  boolean   vb_https
  xmlstream vx_content_part, vx_content
  numeric   vn_chunk_size, vn_poging, vn_timeout, vn_flag, vn_status_send
  string    vs_starttijd, vs_eindtijd
  numeric   vn_starttijd, vn_eindtijd, vn_doorlooptijd
endvariables
   
  pn_status = 0
  pn_http_status = 0
  vn_chunk_size = 1000000
   
  getitem/id vs_url, pl_params, "URL"
  getitem/id vs_username, pl_params, "USERNAME"
  if (vs_username !="")
    vs_username = "%%vs_username%%%(scheme=B)"
  endif
  getitem/id vs_password, pl_params, "PASSWORD"
  getitem/id vs_contenttype, pl_params, "CONTENTTYPE"
  getitem/id vs_charset, pl_params, "CHARSET"
  getitem/id vs_soapaction, pl_params, "SOAPACTION"
  getitem/id vn_timeout, pl_params, "TIMEOUT"
  getitem/id vs_method, pl_params, "METHOD"
  if (vs_method = "")
     vs_method = "GET"
  endif
  getitem/id vb_https, pl_params, "HTTPS"
  getitem/id vs_authorization, pl_params, "Authorization"
  getitem/id vs_accept, pl_params, "Accept"
  strInstance = "UHTTP"
  newinstance "UHTTP", strInstance
   
  ; Set flags vraagt om bits 1, 2 of 3. Dus niet de waarde.
  ; 001 = 1    errors caused by certificate host names that do not match request host names are ignored
  ; 010 = 2    errors caused by expired server certificates are ignored
  ; 100 = 4    the SEND method does not calculate the content-length of the payload itself for a POST method
  ; Om https te kunnen verzenden zijn bits 2 en 3 nodig, dus 2+4=6
  if (vb_https)
    vn_flag = 30
    activate strInstance.set_flags(vn_flag)
  endif
  if (vn_timeout > 0)
    ; timeout in milliseconden.
    if (vn_timeout > 0 & vn_timeout < 100) 
      ; Kleiner dan een tiende seconde? Waarschijnlijk is timeout in seconden opgegeven
      vn_timeout = vn_timeout * 1000
    endif
  else
    vn_timeout = -1
  endif
  activate strInstance.set_timeout(vn_timeout)
  if ($status <0)
    pn_status = $procerror
    pl_status_context = $procerrorcontext
  endif
   
  vx_content = px_request
  ; is het bericht langer dan de chunksize, dan eerst het bericht in stukken aanbieden aan de uhttp component
  length vx_content
  while ($result > vn_chunk_size)
       
    activate "UHTTP".WRITE_CONTENT(vx_content[1:vn_chunk_size])
       
    vx_content = vx_content[vn_chunk_size+1]
    length vx_content
  endwhile
  if (vs_contenttype != "")
    putitem/id vl_http_header, "Content-Type", "%%vs_contenttype%%%"
  else
    putitem/id vl_http_header, "Content-Type", "text/xml"
  endif
  if (vs_soapaction != "")
    putitem/id vl_http_header, "SOAPAction", vs_soapaction
  endif
  putitem/id vl_http_header, "charset", vs_charset
  if (vs_authorization != "")
    putitem/id vl_http_header, "Authorization", vs_authorization
  endif
  if (vs_accept != "")
    putitem/id vl_http_header, "Accept", vs_accept
  endif
  vn_poging = 0
  repeat
    vn_poging = vn_poging + 1
    putitem/id pl_http_header, "REQUEST", vl_http_header 
;    activate strInstance.send(vs_url, "POST"   , vs_username, vs_password, vl_http_header, vx_content, vs_respons_header)
    activate strInstance.send(vs_url, vs_method, vs_username, vs_password, vl_http_header, vx_content, vs_respons_header)
    pn_http_status = $status
    vn_status_send = $status
    putitem/id pl_http_header, "RESPONS", vl_http_header 
    $status = vn_status_send
  until (vn_poging > 2 | $status != -11)
  while ($status = 1)
    activate strInstance.read_content(vx_content_part)
    vx_content = $concat(vx_content, vx_content_part)
  endwhile
  px_respons = vx_content
  if (vx_content != "")
    px_respons = vx_content
  else
    px_respons = vs_respons_header
  endif
  selectcase pn_http_status
    case 0
      ; Bericht is niet verzonden
      pn_status = -1
      putitem/id pl_status_context, "DESCRIPTION", "Bericht is niet verzonden wegens een onbekende fout"
      putitem/id pl_status_context, "COMPONENT", $componentname
    case -10
      ; URL is niet correct
      pn_status = -10
      putitem/id pl_status_context, "DESCRIPTION", "URL is niet correct"
      putitem/id pl_status_context, "COMPONENT", $componentname
    case -11
      ; Timeout van UHTTP component. 
      pn_status = -11
      putitem/id pl_status_context, "DESCRIPTION", "Timeout (%%vn_poging%%% pogingen)"
      putitem/id pl_status_context, "COMPONENT", $componentname
    case -12
      ; INterne fout van UHTTP component. Treedt ook op bij timeout, ga hiervanuit.....
      pn_status = -12
      putitem/id pl_status_context, "DESCRIPTION", "Timeout"
      putitem/id pl_status_context, "COMPONENT", $componentname
    case -13
      ; request is niet correct
      pn_status = -13
      putitem/id pl_status_context, "DESCRIPTION", "Request is niet correct"
      putitem/id pl_status_context, "COMPONENT", $componentname
    case 200
      pn_status = 0
      putitem/id pl_status_context, "DESCRIPTION", "Bericht is verzonden."
      putitem/id pl_status_context, "COMPONENT", $componentname
    elsecase
      ;if ($status > 0)
      if (pn_http_status > 0) ; http status
        pn_status = 1
        putitem/id pl_status_context, "COMPONENT", $componentname
        putitem/id pl_status_context, "DESCRIPTION", vs_respons_header
      else
        pn_status = $procerror
        pl_status_context = $procerrorcontext
      endif
  endselectcase
end ; send
Component "SOMTODAY" Defines:
; Your component defines here (optional)...
#define client_id D50E0C06-32D1-4B41-A137-A9A850C892C2
#define true  1
#define false 0
#define URL_base https://somtoday.nl
#define URL_organisaties  https://servers.somtoday.nl/organisaties.json
; Your component VARIABLES block here (optional)...
variables
  string    student_id
  string    school_uuid
  string    access_token
  string    refresh_token
  string    access_header
  string    stand_header
  datetime  auth_time
  boolean   bError
  string    somtoday_api_url
  string    somtoday_oop_url
  string    auth_scope
  string    somtoday_tenant
  string    id_token
  string    token_type
  string    auth_expires_in
  date     DIS(yyyy-mm-dd) dtDateyyyymmdd
endvariables
Greetings,
------------------------------
Richard de Vries
Sogeti Nederland B.V.
NL
------------------------------