Skip to content

OpenID Connect Session Management

blevine edited this page Jun 16, 2021 · 2 revisions

mod_auth_openidc supports OpenID Connect Session Management, http://openid.net/specs/openid-connect-session-1_0.html since version 1.6.0.

The OpenID Connect Session Management mechanism uses two hidden iframes that send messages to each other. The content of the first frame - the RP iframe - is served by the Relying Party, mod_auth_openidc in our case, the content of the other - the OP iframe - is served by the OpenID Connect Provider (OP). The RP iframe will periodically check with the OP iframe to see if the session state (stored in a cookie or HTML5 local storage) at the OP has changed, or perhaps the user has logged out from the OP.

If the OP supports session management, it will automatically be used by mod_auth_openidc. However, you need to make sure that HTML pages served to the user contain the two (hidden) iframes. You can do that by including the following code (e.g. just before the </html> tag) in your server side page generation code:

<iframe title='empty' style='visibility: hidden;' width='0' height='0'
  tabindex='-1' id='openidc-op' src='<redirect_uri>?session=iframe_op'
></iframe>
<iframe title='empty' style='visibility: hidden;' width='0' height='0'
  tabindex='-1' id='openidc-rp' src='<redirect_uri>?session=iframe_rp'
></iframe>

Note that the OP iframe id attribute MUST be set to openidc-op!

The src URL in the RP iframe also supports an optional poll parameter that can be set to the number of milliseconds of the interval that the RP iframe uses to poll the OP iframe.

If you serve static HTML only (or you can't or don't feel like changing your server side page generation code) you can use mod_substitute in Apache to add the iframes for you. Here's an example of that:

<Location /protected>
    Authtype openid-connect
    require valid-user
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|</body>|<iframe title='empty' style='visibility: hidden;' width='0' height='0' tabindex='-1' id='openidc-op' src='https://www.example.com/protected/redirect_uri?session=iframe_op'></iframe><iframe title='empty' style='visibility: hidden;' width='0' height='0' tabindex='-1' id='openidc-rp' src='https://www.example.com/protected/redirect_uri?session=iframe_rp\&amp;poll=5000'></iframe></body>|i"
</Location>

Note that doing it in this way is rather coarse grained and it involves some overhead because also pages that don't need session management capabilities (e.g. internal pages served by mod_auth_openidc) will contain and load the iframes.

Logout

RP-initiated logout from the OP is also supported, so when the OP configuration contains a end_session_endpoint, that endpoint will be called during logout from mod_auth_openidc. It is triggered by redirecting the user's browser to the logout endpoint with a parameter that specifies the URL to which the browser should be sent after logout (which would overrride the default one set in the OIDCDefaultLoggedOutURL Apache configuration primitive). An example logout link:

<a href="https://www.example.com/protected/redirect_uri?logout=https%3A%2F%2Fwww.example.com%2Floggedout.html">Logout</a>

Note that the link where the user is sent after logout should not be protected...

If the OP does not support a logout (i.e. does not publish an end_session_endpoint) the logout will kill only the local Apache session that was created and maintained by mod_auth_openidc.

Provider Support

Session Management has been tested against Azure AD after the GA release of OpenID Connect. Steps involved:

  • create an Azure AD account and instance (tenant)
  • register a new client under "Applications", of type "Web Application" and enter your mod_auth_openidc Redirect URI as the Sign-On URL, the App ID URL, and the Reply URL.
  • copy the generated client_id and generate a new client_secret under "keys" in to the mod_auth_openidc config
  • get the OP endpoints from https://sts.windows.net/<tenantid>/.well-known/openid-configuration

Back-channel Logout

See spec

If the OP supports back-channel logout, it will provide a way to specify the back-channel logout URL. This URL can be specified as described above with the addition of a logout=backchannel query parameter. For example:

https://www.example.com/protected/redirect_uri?logout=backchannel