i-TegoDocumentationAuthentification > OpenID Connect OAuth Server dedicated > Develop > OpenID Connect > OpenID Connect : SSO, session management etc.

SSO and Single Login Identification (SLI)

  publié le par i-Tego WM

One expected feature of authorization delegation, which is naturally associated with Single Sign On (SSO), is the ability given to the end user to log in only once to access different applications (Single Login Identification, SLI).

In a standard way, OpenID Connect flows do not allow direct SLI realization, but possibilities exist. We are here on a little disclosed technique, which requires significant development on the application side.

OAuthSD offers the option of managing SLI and silent re-authentication without the need for specific code on the side of client applications. This is discussed in this article : SLI, SLO and SRA are in a boat: OAuthSD.

SSO and SLI

SSO does not automatically imply SLI
When we think about SSO (Single Sign On), we often include two features :
- the fact of only registering once (sign on [1]) on an identity server and being able to connect (enter his login and password) on different applications without having to register on each one. It is strictly speaking the SSO.
- to connect to an application and navigate to another without having to re-enter your login and password. This is the Single Connection or Single Login Identification (SLI).

If the SSO is in the nature of OAuth 2 and OpenID Connect, it is not the same for the SLI. However, OpenID Connect offers "everything you need" to achieve it. Without presenting a particular flow for this : it is therefore a functionality to develop on the side of applications (see : OpenID Connect Session Management), or a new feature to add [2] to OpenID Connect. This is what OAuthSD offers, see : SLI, SLO and SRA are in a boat: OAuthSD.

Of course, SLI is only possible in a set of applications linked to the same identity server, ie in a network and application space controlled by the same entity (corporate realm).

Apps in the same domain

In the case of applications located in the same domain (for example in different subdomains of a main domain, in addition to this domain itself), a simple solution is to share the session cookie between the applications. For this, the application designer will save the cookie for the primary domain instead of saving it for the application subdomain (cookie_domain and cookie_path settings).

However, scopes are unique to applications. The target application must therefore re-query the authorization server to obtain a JWT of its own.

Apps located in different domains

In the case of applications located in different domains the problem is a little more complex.
Authorization forwarding is known to have no secure solution with standard OpenID Connect flows. Indeed, the target application must obtain certainty of the origin of the received token, and therefore the identity of the end user, without being able to impose a new identification request. This is what Silent Re-Authentication, SRA is made for.

Silent Re-Authentication Request (SRA)

The OpenID Connect protocol supports parameter prompt = none on the authentication request that allows applications to indicate that the authorization server should not display any user interaction (such as authentication , the consent). OAuthSD will return the requested response to the application or return an error if the user is not already authenticated, or if a consent type or prompt is required before continuing.

Errors and actions

The possible values ​​for ERROR_CODE are defined by the OpenID Connect specification :

- login_required : The user was not logged in to OAuthSD, silent authentication is not possible.
The user must be redirected to the OAuthSD login page (without prompt = ’none’) in order to authenticate.

- consent_required : The user was connected to OAuthSD, but the application is waiting for its consent (for which a prompt should be displayed, which is excluded by prompt = ’none’).
According to the standard, the user should be redirected to the OAuthSD login page as before.

We have two solutions :

  • avoid this situation by considering that the applications are trusted applications, known to the users, or that the users are sufficiently informed otherwise (for example by presenting them the general conditions of the site to be approved at their first direct connection to the user. ’application). It will be enough to modify the flow not to return an error.
  • edit the feed to submit the consent request rather than return an error.

- interaction_required : The user was logged in to OAuthSD and allowed the application, but must be redirected elsewhere before authentication can be completed, for example, when using a redirect rule .
According to the standard, the user should be redirected to the OAuthSD login page.
This situation should not occur in a corporate realm, where the SLI should be implemented for all client applications. So we come back to the two previous cases.

These errors are returned to the client application that attempted the connection. This involves significant developments in client applications. Fortunately, there is OAuthSD !

Security note :
Querying Authorize with prompt = ’none’ without id_token_hint can not be considered as a user authentication, but as a simple information about its connection.
See : id_token_hint : Silent Re-authentication of subject with ID Token.

OAuthSD goes further ...

In addition to these standard methods which require adaptation of applications, OAuthSD offers the option of manage SLI and silent re-authentication without requiring specific code on the side of the client applications : the authorize controller supports all the work.

SLI, SLO and SRA are in a boat : OAuthSD

  publié le par i-Tego WM

As part of OpenID Connect flows, in addition to the Single Sign On (SSO) function, the OAuthSD server implements the Single Login Identification (SLI) function, the Single Login Out (SLO). as well as Silent Re-Authentication (SRA) [1]. This without modifying the application interface code with OIDC, all being taken into account at the authorize controller.

The OAuthSD server code can be set to implement (or not) the SLI. Single Disconnect (SLO) and Silent Re-Authentication (SRA) are derived from SLI.

Single Identification Identification (SLI)

When the SLI is authorized (ENABLE_SLI = true) AND the client application has been registered on the server with the scope ’sli’, the authorize controller processes a authorization request without a prompt parameter like this :

- The presence of a SLI cookie} recorded on the agent in the server domain (and not in that of the application) is tested,
- if the SLI cookie is present, not expired and validated, it is used for authentication (the login form is not presented to the user), the controller returning the tokens to the client (the code authorization in the case of the authorization flow with code). At this time, the validity of the SLI cookie is refreshed to its initial value.
- In case of failure : either there is a standard return to the client with an error, or the controller presents the login form if the constant REAUTHENTICATE_NO_ROUNDTRIP is true. In either case, the SLI cookie is destroyed first.

- If the SLI cookie is missing :

  • If the client application does not have the ’sli’ scope, the controller acts as standard.
  • If the client application allows the SLI, and if the previously mentioned authentication succeeds, an SLI cookie is registered on the agent in the server domain. This is the only case where the SLI cookie is created.

Notes :
- Any "technical" error (other than the non-repeated errors of the user in the entry of his login or his password) leads to the destruction of the cookie SLI in order to protect the application against the attempts of intrusion. In such a case the server does not respond to not guide the attacker.
- An attempt to connect under a different user ID also causes the destruction of the SLI cookie, and leads to the presentation of the identification form.
- An attempt to connect from a different workstation has the same effect.
- SLI functionality is active in all three OpenID Connect streams, so with the most secure : Authorization with code. This is an advantage over often presented solutions using Implicit flow.
- The behavior of requests with prompt = ’none’, ’login’ and ’consent’ remains in compliance with the standard.
- When the user changes their application and benefits from SLI, consent requests will always be submitted once.

Single Logout Out (SLO)

The server exposes a new logout endpoint, which disconnects the user from all client applications.

The single disconnect request is done as an introspection request by providing the identity token.

When disconnection is performed, all access tokens stored on the server for the subject in question are erased. As a result, SLI cookies that may be present on the user’s agents will be destroyed if a connection attempt is made.

Note that client applications must handle the disconnect at their level, there is no miracle !

If you want to know the current connection status of an application, simply repeat the authentication request with prompt = ’none’. If the disconnection has occurred, the server will respond with ’login_required’. This solution has the advantage of fully meeting the OpenID Connect standard in its final state.

Silent Re-Authentication (SRA)

As part of the OAuthSD server, this feature is a direct result of the SLI [2].

For applications that do not allow SLI, they do not benefit from the SRA. But it is likely that the reasons that led to not allowing the SLI would lead to not authorizing the SRA.

Note that it is always possible to Rafraîchir (actualiser) un jeton d’accès.

See also : id_token_hint : Silent Re-authentication of subject with ID Token.

The SLI Cookie

The SLI cookie is a DnC-specific concept that allows the OAuthSD server to offer all the features of single sign-on (SLI, SLO, SRA, SLO) without modifying client applications provided they are already interfaced with OpenID Connect. Given the complexity and diversity of the solutions proposed elsewhere, which have not made a definitive specification (early 2019), this is a major contribution of OAuthSD to OpenID Connect.

The SLI cookie is created by the Authorize controller if the SLI is authorized for the client application (scope ’sli’).

Il existe des informations complémentaires, connectez vous pour les voir.

Notes

[1These features are often understood as part of the SSO, but strictly speaking SSO means "single sign-on".

[2Other implementations involve many developments on the application side (see OpenID Connect Session Management). The solution offered by OAuthSD has the enormous advantage of not requiring any modification to the client application. However, the solution is not standard. Since OpenID Connect session management is the subject of a standard proposal, OAuthSD will also offer this method in the future.

Monitoring the state of authentication and Single Log Out (SLO)

  publié le par i-Tego WM

The purpose of the authentication status monitoring is to synchronize the local connection of an application with the corresponding access token.

Introduction

OAuthSD, following OAuth 2.0, considers that the end user is connected to an application as long as the associated access token is valid.

There is no "naturally" direct relationship between this token and the local connection state of an application. Each application will have to set up a monitoring, client side, in order to :
- monitor the validity of the access token,
- complete the Single Logout (SLO) mechanism by causing local disconnection of the application when the access token has expired.

1. The community is offered a "standard" for managing the OpenID Connect session (see : OpenID Connect Session Management ) which relies on iframes on the server side and on the application side.

In version 30 published in August 2020, a section disappears that was present in version 28 and was entitled "Back-Channel Logout".
Indeed, a new proposal "OpenID Connect Back-Channel Logout" avoid the malfunctions that were mentionned in paragraph "User Agents Blocking Access to Third-Party Content" :

Note that at the time of this writing, some User Agents (browsers) are starting to block access to third-party content by default to block some mechanisms used to track the End-User’s activity across sites. Specifically, the third-party content being blocked is website content with an origin different that the origin of the focused User Agent window. Site data includes cookies and any web storage APIs (sessionStorage, localStorage, etc.).

This can prevent the ability for notifications from the OP at the RP from being able to access the RP’s User Agent state to implement local logout actions. In particular, cookies and web storage APIs may not be available in the OP frame loaded in the RP context. The side effect here is that, depending on the used mechanism (cookies or web storage), the data needed to recalculate session_state might not be available. Cookie based implementations might then return changed for every single call, resulting in infinite loops of re-authentications. Therefore, deployments of this specification are recommended to include defensive code to detect this situation, and if possible, notify the End-User that the requested RP logouts could not be performed. The details of the defensive code needed are beyond the scope of this specification ; it may vary per User Agent and may vary over time, as the User Agent tracking prevention situation is fluid and continues to evolve. ".

A specification proposal which has undergone 30 modifications but which has not changed since August 2020, and which also ends with a finding of malfunction, is dead !

Moreover, we think (maybe wrongly ?) that a "standard" for a protocol-level ISO layer should not impose a process on a lower-level layer.

2. Our solution presented here : Implementation of monitoring with Javascript : examples for SPIP and WordPress therefore interrogate the Authorize controller with the parameter display = "none".
A client-side implementation based on the OpenID Connect standard as it currently exists is much preferable to a further complication of client applications and helps avoid violation of the principle of ISO layer independence.

In support of this statement, we present monitoring methods implemented for SPIP and WordPress :

Implementation of the monitoring in the OpenID Connect client plugin for SPIP

The oa.dnc.global site uses this plugin (it is OIDC client, the snake is biting its tail !). You can see a label at the top left of the window that reflects the status of the access token linked to the current connection :

icon Meaning
The end user connection is not established with the OIDC server. Note that the user may have logged in to the application using the classic SPIP login method.
The end user and the application are connected by OIDC.
General error, unfortunately translates multiple situations :
- loss of Internet communication,
- default configuration of the plugin,
- failure to register the client application on the OAuthSD server,
- registration of the application on another server, not compatible with OAuthSD,
- unknown login of the OAuthSD server (the end user is not registered on this server),
- etc.
The message may be more explicit : "authentication error", ...

The Monitoring also allows to manage the OIDC session and in particular to perform the global disconnection (SLO).
By clicking on the icon, popups appear depending on the connection status.

Example of the Javascript code (with jQuery) used for SPIP. The plugin inserts this code at the bottom of each page.
[SPIP]

  1. /**
  2. * Plugin OpenID Connect client pour SPIP
  3. * OIDC Client Monitoring
  4. * Interroge le contrôleur OIDC Authorize avec prompt=none pour afficher l'état de connexion.
  5. * Voir également action_logout() dans oidcclient_options.php.
  6. * Auteur : B.Degoy DnC
  7. * Copyright (c) 2019 B.Degoy
  8. * Licence GPL v3.0
  9. */
  10.  
  11.     // OIDC Client Monitoring
  12.  
  13.     <?php
  14.     include_spip('inc/oidcclient_configuration'); ?>
  15.  
  16.     $(document).ready(function() {
  17.  
  18.         // Ajouter l'étiquette si elle n'existe pas
  19.         if($('#oidc').length === 0){
  20.             $('<div id="oidc">&nbsp;OIDC&nbsp;</div>   ')
  21.             .appendTo('nav')
  22.             .css('position','absolute')
  23.             .css('top','12px')
  24.             .css('left','3px')
  25.             .css('color','white')
  26.             .css('padding','3px');    
  27.         }
  28.  
  29.         var login = "<?php echo @$GLOBALS['visiteur_session']['login']; ?>";
  30.         var state = "<?php echo @$GLOBALS['visiteur_session']['state']; ?>";
  31.  
  32.         if ( login !== "" ) {
  33.             // Si on est logé localement, surveiller qu'on l'est également sur OIDC
  34.             setInterval(function(){
  35.                 $.ajax({
  36.                     type : "get",
  37.                     url : "<?php echo OIDC_AUTHORIZATION_ENDPOINT; ?>",
  38.                     data : { 'response_type' : 'code',
  39.                         'client_id' : "<?php echo OIDC_CLIENT_ID; ?>",
  40.                         'user_id' : login,
  41.                         'state' : state,
  42.                         'scope' : 'openid',
  43.                         'prompt' : 'none',
  44.                     },
  45.                     statusCode : {
  46.                         401 : function(){
  47.                             // Non authentifié sur OIDC, déconnecter localement
  48.                             var url_logout_public = "<?php echo '?action=logout&logout=local&url=' . $GLOBALS['REQUEST_URI']; ?>";
  49.                             window.location.replace(url_logout_public);
  50.                         },
  51.                         200 : function (){
  52.                             // Signaler la connexion
  53.                             $('#oidc').css('background-color', '#8f8');
  54.                             $('#oidc').text(' OIDC ');
  55.                         },
  56.  
  57.                     },
  58.                     error : function(obj,textStatus,errorThrown){
  59.                         // Signaler qu'on ne sait pas
  60.                         $('#oidc').css('background-color', 'red');
  61.                         $('#oidc').text(textStatus + ' ' + errorThrown);
  62.                     }
  63.                 });    
  64.             }, 2000);
  65.  
  66.         } else {
  67.             // Signaler la déconnexion
  68.             $('#oidc').css('background-color', 'orange');
  69.             $('#oidc').text(' OIDC ');
  70.         }
  71.  
  72.     });

Télécharger

Implementing monitoring in a Wordpress app

  The plugin is available on Github.

The Javascript code is inserted into a hook called by the bootstrap () function of the extension :

[PHP]

  1. /**
  2.     * OAuthSD project https://oa.dnc.global
  3.     * OAuthSD OIDC plugin for WordPress
  4.     * Insert monitoring code in footer
  5.     * dnc1
  6.     * Author : bdegoy DnC https://degoy.com
  7.     * copyright (c) 2019 B.Degoy DnC
  8.     * Licence GPL v3.0
  9.     */
  10.  
  11.     function insert_monitoring() {
  12.      
  13.         // Enqueue some jQuery UIs
  14.         wp_enqueue_script('jquery-ui-dialog'); // from WP core
  15.         // get registered script object for jquery-ui
  16.         global $wp_scripts;
  17.         $ui = $wp_scripts->query('jquery-ui-core');
  18.         // load the Smoothness theme from Google CDN  
  19.         $protocol = is_ssl() ? 'https' : 'http';
  20.         $url = "$protocol://ajax.googleapis.com/ajax/libs/jqueryui/{$ui->ver}/themes/smoothness/jquery-ui.min.css";
  21.         wp_enqueue_style('jquery-ui-smoothness', $url, false, null);
  22.            
  23.         // OIDC Client Monitoring
  24.         $thisuri = $_SERVER['REQUEST_URI'];
  25.         $absolutepath_this_plugin = plugin_dir_path( __FILE__ );
  26.         $url_this_plugin = plugins_url('', dirname(__FILE__) ) . "/openid-connect-generic";
  27.         $state = md5(wp_get_session_token());
  28.        
  29.         // Server URLs
  30.         $settings = $this->settings;
  31.         $url_endpoint_login = $settings->endpoint_login;
  32.         $url_endpoint_token = $settings->endpoint_token;
  33.         $url_endpoint_userinfo = $settings->endpoint_userinfo;
  34.         $url_endpoint_logout = $settings->endpoint_end_session;
  35.         $parts = parse_url($url_endpoint_login);
  36.         $url_server = $parts['scheme'] . '://' . $parts['host'];
  37.        
  38.         // OIDC user
  39.         $clientID = $settings->client_id;
  40.         // $userID = ???
  41.        
  42.         // WP user
  43.         $user = get_user_by('id', get_current_user_id());
  44.         $login = $user->user_login;
  45.         $nom_auteur =$user->display_name;
  46.        
  47.         // for info popup
  48.         $infos =
  49.         '<br/>' . __('oidcclient:serveur_url','openid-connect-generic') . ' : <a href="' . $url_server . '">' . $url_server . '</a>' .
  50.         '<br/>' . __('oidcclient:client_id','openid-connect-generic') . ' : ' . $clientID .
  51.         '<br/>' . __('oidcclient:login_wp','openid-connect-generic') . ' : ' . $login .
  52.         //'<br/>' . __('oidcclient:login_oidc_court','openid-connect-generic') . ' : ' .  $userID .
  53.         '<br/>' . __('oidcclient:nom_auteur','openid-connect-generic') . ' : ' .  $nom_auteur;
  54.        
  55.         // labels and messages
  56.         $msg_session_connected_no = __('oidcclient:session_connected_no','openid-connect-generic');
  57.         $msg_session_connected_yes = __('oidcclient:session_connected_yes','openid-connect-generic');
  58.         $msg_session_connected_error = __('oidcclient:session_connected_error','openid-connect-generic');
  59.         $msg_session_open = __('oidcclient:session_open','openid-connect-generic');
  60.         $msg_session_extend = __('oidcclient:session_extend','openid-connect-generic');
  61.         $msg_session_close = __('oidcclient:session_close','openid-connect-generic');
  62.         $msg_session_expires = __('oidcclient:session_expires','openid-connect-generic');
  63.         $lbl_yes = __('oidcclient:item_yes','openid-connect-generic');
  64.         $lbl_no = __('oidcclient:item_no','openid-connect-generic');
  65.         $lbl_t_session_restant = __('oidcclient:t_session_restant','openid-connect-generic');
  66.         $lbl_delai_reponse = __('oidcclient:delai_reponse','openid-connect-generic');
  67.         $lbl_infos_titre = __('oidcclient:lbl_infos_titre','openid-connect-generic');
  68.        
  69.         // link to OIDC login                                                                                        
  70.         $link_login = $this->client_wrapper->get_authentication_url();
  71.        
  72.         // link to logout page
  73.         $url_logout = esc_url($url_this_plugin . "/oidc_logout.php?url=" . $_SERVER['REQUEST_URI']);
  74.    
  75.         echo <<<JSCODE
  76.            
  77. <script type="text/javascript">
  78.    
  79. (function($) {
  80.  
  81.     var login = "$login";
  82.     var timeleft = 0;
  83.     var connected = 0;
  84.     var connectionMsg = '';
  85.     var interval = null;
  86.     var pollperiod = 60000;
  87.     var tagappendto = '#content';
  88.     var tagtop = '120px';
  89.     var tagleft = '16px';
  90.     var responseDelay = 'Unk';
  91.  
  92.     $(document).on('ready',function(){
  93.  
  94.         // Add OIDC labels
  95.         if($('#oidc').length === 0){
  96.             $('<div id="oidc"><span id="oidctag">&nbsp;OIDC&nbsp;</span><span id="oidcinfo">&nbsp;?&nbsp;</span></div>')
  97.             .appendTo(tagappendto);
  98.             //
  99.             $('#oidc')
  100.             .css('position','absolute')
  101.             .css('top',tagtop)
  102.             .css('left',tagleft);
  103.             //
  104.             $('#oidctag')
  105.             .css('color','white')
  106.             .css('padding','3px')
  107.             .css('z-index','10000')
  108.             .on('click', function(){
  109.                 switch (connected) {
  110.                     case 0 :
  111.                         connectionMsg = "$msg_session_connected_no";
  112.                         SessionOpenDialog(connectionMsg);
  113.                         break;
  114.                     case 1 :
  115.                         connectionMsg = "$msg_session_connected_yes";
  116.                         SessionCloseDialog(connectionMsg);
  117.                         break;
  118.                     default :
  119.                     case -1 :
  120.                         connectionMsg = "$msg_session_connected_error";
  121.                         break;
  122.                 };
  123.             });
  124.             //
  125.             $('#oidcinfo')
  126.             .css('color','white')
  127.             .css('padding','3px')
  128.             .css('z-index','10001')
  129.             .css('background-color','#09f')
  130.             .on('click', function(){
  131.                 $('<div></div>').appendTo('body')
  132.                 .html('<div><h6>$infos<br/>$lbl_t_session_restant : ' + timeleft + ' s<br/>$lbl_delai_reponse : ' + responseDelay + ' ms</h6></div>')
  133.                 .dialog({
  134.                     modal: true, title: "$lbl_infos_titre", zIndex: 10000, autoOpen: true,
  135.                     width: 'auto', resizable: false,
  136.                     close: function (event, ui) {
  137.                         $(this).remove();
  138.                         interval = setInterval(pollOidc,pollperiod);
  139.                         }
  140.                     });
  141.                 }
  142.             );            
  143.         }
  144.  
  145.         // If user is logged locally, verify the OIDC session is valid.  
  146.         if ( login !== "" ) {
  147.             pollOidc();
  148.             interval = setInterval(pollOidc,pollperiod);
  149.  
  150.         } else {
  151.             connected = 0;
  152.             // Show not OIDC connected.
  153.             $('#oidctag').css('background-color', 'orange');
  154.             $('#oidctag').text(' OIDC ');
  155.         }
  156.  
  157.         function SessionCloseDialog(message) {    //[dnc28d]
  158.             clearInterval(interval);
  159.             $('<div></div>').appendTo('body')
  160.             .html('<div><h6>'+message+'?</h6></div>')
  161.             .dialog({
  162.                 modal: true, title: "$msg_session_close", zIndex: 10000, autoOpen: true,
  163.                 width: 'auto', resizable: false,
  164.                 buttons: [
  165.                     {
  166.                         text: "$lbl_yes",
  167.                         click: function () {
  168.                             // Close the OIDC session.
  169.                             window.location.replace("$url_logout");
  170.                             $(this).dialog("close");
  171.                         }
  172.                     },{
  173.                         text: "$lbl_no",
  174.                         click: function () {                                                              
  175.                             $(this).dialog("close");
  176.                             interval = setInterval(pollOidc,pollperiod);
  177.                         }
  178.                     }
  179.                 ],
  180.                 close: function (event, ui) {
  181.                     $(this).remove();
  182.                     interval = setInterval(pollOidc,pollperiod);
  183.                 }
  184.             });
  185.         };
  186.  
  187.         function SessionOpenDialog(message) {    //[dnc28d]
  188.             clearInterval(interval);
  189.             $('<div></div>').appendTo('body')
  190.             .html('<div><h6>'+message+'?</h6></div>')
  191.             .dialog({
  192.                 modal: true, title: "$msg_session_open", zIndex: 10000, autoOpen: true,
  193.                 width: 'auto', resizable: false,
  194.                 buttons: [
  195.                     {
  196.                         text: "$lbl_yes",
  197.                         click: function () {
  198.                             // Se connecter
  199.                             window.location.replace("$link_login");
  200.                             $(this).dialog("close");
  201.                         }
  202.                     },{
  203.                         text: "$lbl_no",
  204.                         click: function () {                                                                
  205.                             $(this).dialog("close");
  206.                             interval = setInterval(pollOidc,pollperiod);
  207.                         }
  208.                     }
  209.                 ],
  210.                 close: function (event, ui) {
  211.                     $(this).remove();
  212.                     interval = setInterval(pollOidc,pollperiod);
  213.                 }
  214.             });
  215.         };
  216.  
  217.         function ExtendDialog(message) {    //[dnc28d]
  218.             if ( !$("#extenddialog").size() ) {  //[dnc28f]
  219.                 clearInterval(interval);
  220.                 $('<div id="extendeddialog"></div>').appendTo('body')
  221.                 .html('<div><h6>'+message+'?</h6></div>')
  222.                 .dialog({
  223.                     modal: true, title: "$msg_session_extend", zIndex: 10000, autoOpen: true,
  224.                     width: 'auto', resizable: false,
  225.                     buttons: [
  226.                         {
  227.                             text: "$lbl_yes",
  228.                             click: function () {
  229.                                 // Extend session
  230.                                 $.ajax({
  231.                                     type : "get",
  232.                                     url : "$url_endpoint_login",
  233.                                     data : { 'response_type' : 'code',
  234.                                         'client_id' : "$clientID",
  235.                                         'user_id' : login,
  236.                                         'state' :  "$state",
  237.                                         'scope' : 'openid sli',
  238.                                     }
  239.                                 });
  240.                                 $(this).dialog("close");
  241.                                 interval = setInterval(pollOidc,pollperiod);
  242.                             }
  243.                         },{
  244.                             text: "$lbl_no",
  245.                             click: function () {                                                                
  246.                                 $(this).dialog("close");
  247.                                 interval = setInterval(pollOidc,pollperiod);
  248.                             },
  249.                         }
  250.                     ],
  251.                     close: function (event, ui) {
  252.                         $(this).remove();
  253.                         interval = setInterval(pollOidc,pollperiod);
  254.                     },
  255.                 });
  256.             }
  257.         };
  258.  
  259.         // Test OIDC connection.
  260.         function pollOidc(){
  261.             connected = -1;
  262.             var d = new Date();
  263.             var timeStart = d.getTime();
  264.             var timeStop = 0;
  265.             $.ajax({
  266.                 type : "get",
  267.                 url : "$url_endpoint_login",
  268.                 data : { 'response_type' : 'code',
  269.                     'client_id' : "$clientID",
  270.                     'user_id' : login,
  271.                     'state' :  "$state",
  272.                     'scope' : 'openid',
  273.                     'prompt' : 'none',
  274.                 },
  275.                 statusCode : {
  276.                     401 : function(){
  277.                         connected = 0;
  278.                         var d = new Date();
  279.                         timeStop = d.getTime();
  280.                         // Not (or no longer) connected on OIDC, disconnect locally
  281.                         window.location.replace("$url_logout" +"&logout=local");
  282.                     },
  283.                     200 : function ( data, textStatus, jqXHR){
  284.                         connected = 1;
  285.                         var d = new Date();
  286.                         timeStop = d.getTime();
  287.                         // Show OIDC connected
  288.                         $('#oidctag').css('background-color', '#8f8');
  289.                         $('#oidctag').text(' OIDC ');
  290.                         timeleft = data['timeleft'];
  291.                         if ( timeleft < 600 ) {  //[dnc28d]
  292.                             // Approaching OIDC session end.
  293.                             clearInterval(interval);
  294.                             ExtendDialog("$msg_session_expires");
  295.                             interval = setInterval(pollOidc,pollperiod);
  296.                         }
  297.                     },
  298.                 },
  299.                 error : function(obj,textStatus,errorThrown){
  300.                     connected = -1;
  301.                     // Show error (OIDC state is unknown)
  302.                     $('#oidctag').css('background-color', 'red');
  303.                     $('#oidctag').text(textStatus + ' ' + errorThrown);
  304.                 },
  305.                 complete : function ( data, textStatus, jqXHR){
  306.                     if ( timeStop && timeStart ) {
  307.                         responseDelay = timeStop - timeStart;      
  308.                     } else {
  309.                         responseDelay = 'Unk';
  310.                     }
  311.                 },
  312.             });    
  313.         }
  314.  
  315.     });
  316. })( jQuery );
  317.  
  318. </script>
  319.  
  320. JSCODE
  321. ;
  322.    
  323. } //function

Télécharger

Note that you must insert a div block at the bottom of the page, which is done by means of an action in the bootstrap function at the same time as the hook of the previous function :

[PHP]

  1. //OIDC Monitoring
  2.         wp_enqueue_script("jquery");
  3.         add_action('wp_footer', array( $plugin, 'insert_monitoring'), 5);

Télécharger