Hans Zandbelt edited this page Aug 12, 2018 · 68 revisions

Frequently Asked Questions

1. How do I configure mod_auth_openidc?

Take a look at the (simple) examples in the README.md first:
For an exhaustive overview of all configuration options, see:

Here are some walkthrough articles on the web for a configuration against Google:

2. After authentication with my Provider there's an error on return.

This is usually a problem with the Cookie settings. Make sure that your OIDCRedirectURI is a path that is protected by mod_auth_openidc, also make sure that the target URL that you access matches the <proto>://<host>/<path> setting of OIDCRedirectURI and (when in use) make sure you align the OIDCCookiePath and/or OIDCCookieDomain settings with both the OIDCRedirectURI and the target application URL as well.

3. What about sessions and caching?

See: https://github.com/pingidentity/mod_auth_openidc/wiki/Caching

4. How can I use the Access Token and Refresh Tokens?

See: https://github.com/pingidentity/mod_auth_openidc/wiki/Access-Tokens-and-Refresh-Tokens

5. How can I get more claims from the OpenID Connect Provider?

By adding additional scopes in the OIDCScope setting as in:

OIDCScope "openid email profile"

(the openid scope always needs to be part of the requested scopes)
In a multi-provider setup this setting functions as the default and you can override it for a specific provider in the .conf file for that provider using the scope key, e.g.

"scope": "openid email profile"

6. Why don't I see any HTTP headers being set in my browser?

The headers are not passed to the browser; they are set server-side only and can only be read by the protected application. This is for (obvious) security reasons and in fact any suspicious headers (i.e. starting with OIDC_ or the configured OIDCClaimPrefix) set by the browser will be scrubbed.

7. Will mod_auth_openidc work when combined with Apache Proxy modules (mod_proxy_*)?

Yes, you may have to fiddle (or not) with the module loading order but it will work. In fact this is a primary usecase that allows you to deploy an Apache Proxy in front of the applications you want to protect so you can enable OpenID Connect authentication for your applications without touching the application's code. The user identity information will be passed to your application in HTTP headers (and, if enabled, the REMOTE_USER header).

8. How do I run mod_auth_openidc behind a (reverse) proxy?

mod_auth_openidc can be deployed behind a proxy by having that proxy pass in the X-Forwarded-Proto and X-Forwarded-Port headers to make mod_auth_openidc aware of the external protocol (http/https) and port that browsers use to access the protected application. The proxy also needs to preserve the Host header that is sent by the browser, e.g. in an Apache Proxy one would use ProxyPreserveHost configuration primitive to do that. Alternatively the proxy can send the original hostname in the X-Forwarded-Host header.

9. How do I logout users?

You can kill the session from your application by redirecting the user to the OIDCRedirectURI with a parameter named logout. The value of that parameter contains the (URL-encoded) URL where the user will be redirected to after the session has been killed. For example, a logout link on the protected HTML page could look like:

<a href="/protected/redirect_uri?logout=https%3A%2F%2Flocalhost%2Floggedout.html">Logout</a>

Note: make sure that the (URL-encoded) callback URL passed in the logout parameter points to a location that is not protected by mod_auth_openidc or else the login process will be started again... (and most likely SSO will occur).

If the OP supports Session Management then the user will be redirected to the Provider for logout as well.

If the OP supports Front Channel Logout mod_auth_openidc can respond to Logout request initiated by the Provider. In that case the frontchannel_logout_uri for the mod_auth_openidc Client should have been set to <OIDCRedirectURI>?logout=get.

If the OP is PingFederate and the "OpenID Connects Settings" in the "Authorization Server Settings" have been configured with "Track User Sessions for Logout", then the "Logout URIs" for the *mod_auth_openidc Client should be set to <OIDCRedirectURI>?logout=img.

10. Can you show me a simple application?

Here's a minimal PHP sample application:

    <h1>Hello, <?php echo($_SERVER['REMOTE_USER']) ?></h1>
    <pre><?php print_r(array_map("htmlentities", apache_request_headers())); ?></pre>
    <a href="/protected/redirect_uri?logout=https%3A%2F%2Flocalhost%2Floggedout.html">Logout</a>

11. Where can I get binary packages?

You can download binary .deb packages for the latest release for Debian/Ubuntu, CentOS/Redhat and Windows from the Github Releases pages.

mod_auth_openidc is also available through the package repositories of various Linux distributions through typically that results in an older version.

FreeBSD users can use one of the following two options to install mod_auth_openidc:

  • To install the port: cd /usr/ports/www/mod_auth_openidc/ && make install clean
  • To add the package: pkg install ap24-mod_auth_openidc

12. How can I customize the IDP Discovery (or: initial login) page?

Basically the answer is in the README.md (see OIDCDiscoveryURL). Below is a simple example of a custom static discovery page in plain HTML where metadata for the (2) providers has been preconfigured in OIDCMetadataDir and a static deep link target (/protected/index.html) is used:

  <p><a href="https://localhost/protected/?iss=accounts.google.com&amp;target_link_uri=https%3A%2F%2Flocalhost%2Fprotected%2Findex.html">
  <p><a href="https://localhost/protected/?iss=seed.gluu.org&amp;target_link_uri=https%3A%2F%2Flocalhost%2Fprotected%2Findex.html">

Note: if you want to preserve POST data across authentication requests (see: OIDCPreservePost for versions >= 2.0) you'll need to accept and return a dynamic method parameter as well, so that requires a setup that is able to parse and return HTTP query parameters like below.

Next is a more advanced PHP example that reads dynamically registered metadata from OIDCMetadataDir (/var/cache/mod_auth_openidc/metadata/) and provides OpenID Connect Provider Discovery and uses a dynamic deep link target:



$oidc_callback = $_GET['oidc_callback'];
$metadata_dir = '/var/cache/mod_auth_openidc/metadata/';

if ($handle = opendir($metadata_dir)) {
        while (false !== ($entry = readdir($handle))) {
                $type = ".provider";
                $len = strlen($type);
                if (substr($entry, -$len) !== $type) continue;
                $json = json_decode(file_get_contents($metadata_dir . $entry));
                echo '<p><a href="' . htmlspecialchars($oidc_callback . "?iss=" . urlencode($json->issuer) . "&" . $_SERVER['QUERY_STRING']) . '">' . htmlspecialchars($json->issuer) . '</a></p>';


<form method="GET" action="<?php echo $oidc_callback ?>">
  <p>Or enter your account name, your IDP identifier or your IDP's domain name:</p>
  <input type="text" name="iss">
    foreach ($_GET as $key => $value) {
      echo '<input type="hidden" name="' . $key . '" value="' . $value . '">';
  <button type="submit">Submit</button>

13. How can I add custom parameters to the authorization request?

  • a. When using a single statically configured provider, you can add one ore more URL-encoded <name>=<value parameters to the OIDCAuthRequestParams in the Apache configuration, as in:

    OIDCAuthRequestParams hd=example.com&approval_prompt=force
  • b. If you're using multiple OPs you can create a file named <url-encoded-issuer>.conf in the metadata directory and set the auth_request_params parameter so that it looks like:

        "auth_request_params" : "<param-name1>=<urlencoded-param-value1>&<param-name2>=<urlencoded-param-value2>&<etc.>"

    The setting for OIDCAuthRequestParams will function as the default for multiple OPs when no explicit auth_request_params has been set for an OP.

  • c. When using multiple OPs and you need to pass in parameters determined at runtime during the discovery phase, you can use additional mod_auth_openidc specific parameter named auth_request_params in the discovery response, as in:


Its value would contain dynamically determined custom parameters that need to be passed in the authorization requests and as such it is the runtime equivalent of the static OIDCAuthRequestParams configuration value and the auth_request_params in the .conf file. If you use more than one of the previous settings you'll need to make sure they do not conflict. Note that nested URL encoding is required e.g. passing both prompt=consent and max_auth_age=0 would result in:

  • d. Lastly and deprecated, for versions of mod_auth_openidc older than 1.6.0 and configurations that don't use OIDCProviderMetadataURL or need to override the authorization_endpoint setting in there, you can also set the OIDCProviderAuthorizationEndpoint and add parameters to that, as in:

    OIDCProviderAuthorizationEndpoint https://accounts.google.com/o/oauth2/auth?hd=example.com&approval_prompt=force

Since version 2.3.0 there is also an option to add custom parameters to the authentication request based on the path that is accessed with OIDCPathAuthRequestParams, typically used to realize step-up authentication scenario's, see: https://github.com/pingidentity/mod_auth_openidc/wiki/Step-up-Authentication

14. Does mod_auth_openidc provide migration of Google's OpenID 2.0 identifiers to OpenID Connect?

Yes, by using a custom parameter in the authentication request as described in the previous question. For Google accounts one can add the "openid.realm" parameter to the authentication request with the value of your OpenID realm to obtain OpenID 2.0 identifiers for migration purposes as described in #29. The OpenID 2.0 identifier will be returned in the openid_id claim and it will be passed in the HTTP header OIDC_CLAIM_openid_id. For Google documentation on the migration, see: https://developers.google.com/accounts/docs/OpenID#openid-connect

15. Does mod_auth_openidc implement OpenID Connect Session Management?

Yes, the functionality as specified in OpenID Connect Session Management draft 21 was added since release 1.6.0, see: https://github.com/pingidentity/mod_auth_openidc/wiki/Session-Management.

16. What does a minimal Apache configuration file look like?

Listen 443
User www
Group www
DocumentRoot <path>
ErrorLog "logs/error_log"
LogLevel info
ServerName <hostname>

LoadModule ssl_module modules/mod_ssl.so
LoadModule auth_openidc_module modules/mod_auth_openidc.so

<VirtualHost _default_:443>
  SSLEngine on
  SSLCertificateFile <path>
  SSLCertificateKeyFile <path>
  SSLCertificateChainFile <path>

  OIDCProviderMetadataURL <url>

  OIDCClientID <client_id>
  OIDCClientSecret <client_secret>

  OIDCCryptoPassphrase <password>

  OIDCRedirectURI https://<hostname>/redirect_uri

  <Location "/">
    AuthType openid-connect
    Require claim sub:<userid>


17. Restricted web server environments

In some environments it is not possible to connect directly to the Internet. If this is the case, it will prevent Apache from retrieving the OIDCProviderMetadataURL and result in an HTTP 500 error. You will see these messages in Apache's error log:

oidc_util_http_call: curl_easy_perform() failed on: https://my.op.org/.well-known/openid-configuration (Failed to connect to my.op.org port 443: Connection refused)

Such environments may deploy HTTP proxies to offer outside connectivity, for instance by setting the environment variables http_proxy or https_proxy. You might need to explicitly configure Apache to use these in your vhost configuration:

SetEnv https_proxy "http://proxy.example.com"

You will also need to set OIDCOutgoingProxy as documented here: https://github.com/pingidentity/mod_auth_openidc/blob/master/auth_openidc.conf#L651

18. How do the state and session cookies work?

See: https://github.com/pingidentity/mod_auth_openidc/wiki/Cookies

19. How do I customize the user-facing error pages?

You can use the OIDCHTMLErrorTemplate configuration directive to do that. The template must be prepared to take two strings, an error title and a more detailed error description, both HTML encoded values, in that order and referenced by (C-style) "%s", e.g.


A minimal example that posts error+detail to another webpage:

<html><body onload="document.forms[0].submit()">
  <form method="post" action="http://example.org/error">
    <input name="error" value="%s">
    <input name="description" value="%s">
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.