Known Limitations - OpenIDC/mod_auth_openidc GitHub Wiki
Parallel Rolling Refresh Token Grants
When the Authorization Server rotates refresh tokens, mod_auth_openidc runs in a cluster, and is configured with OIDCRefreshAccessTokenBeforeExpiry
and/or OIDCUserInfoRefreshInterval
, parallel requests may lead to an inconsistent state across the cluster nodes. Note the the position of the OpenID Foundation working group on the use of rotating refresh tokens:
NOTE 1: The use of refresh token rotation does not provide security benefits when used with confidential clients and sender-constrained access tokens. This specification prohibits the use of refresh token rotation for security reasons as it causes user experience degradation and operational issues whenever the client fails to store or receive the new refresh token and has no option to retry.
However, as refresh token rotation may be required from time to time for infrastructure migration or similar extraordinary circumstances, this specification allows it, provided that authorization servers offer clients the time-limited option to retry with the old refresh token in case of failure. Implementers need to consider a secure mechanism for clients to recover from a loss of a new refresh token on issue. The details of this mechanism are outside the scope of this specification.
When using OIDCRefreshAccessTokenBeforeExpiry
and/or OIDCUserInfoRefreshInterval
requests originating from the same user/session reaching different Apache processes simultaneously may lead to execution of several refresh token grants in parallel which could lead to issuance of overlapping/invalidated refresh tokens when used with rolling refresh tokens. The last issued refresh token may be overwritten in the session with an earlier one and as such may lead to an unrecoverable situation.
A mitigation has been added since 2.4.15.3 to avoid this by caching and re-using the result of the first token refresh grant request. This also improves the situation with persistent refresh tokens as previously these requests would lead to multiple access tokens and ID tokens being issued for the same session (with the last one winning). This mechanism guarantees correct handling of parallel refresh requests on a single host using a system wide process lock.
A "best effort distributed parallel refresh prevention" is used to prevent this issue when rolling refresh tokens are used across different Apache servers. The first caller writes a "best effort lock" into the shared cache backend upon starting the refresh token request and the other callers wait for its completion to consume its results. Note that since the server cache backend cannot be atomically locked across multiple hosts, this is not 100% failsafe, so the advice is still to not use rolling refresh tokens with clustered Apache servers, unless using sticky sessions.
Lastly, rolling refresh tokens must not be used together with OIDCSessionType client-cookie
when there is no shared caching mechanism in use between the Apache servers (i.e. when using OIDCCacheType shm
, which is usually the reason for using client-cookie
). Sticky sessions can be used to mitigate the issue here as well.
POST Data Preservation (1)
Preservation of POST data with OIDCPreservePost On
over session timeouts and newly initiated sessions is only supported with simple name/value pairs i.e. using Content-Type: application/x-www-form-urlencoded
, not arbitrary (streamed) POST data.
POST Data Preservation (2) and Authorization / Step-Up Authentication
Preservation of POST data combined with OIDCPreservePost On
and Authorization using Require claim
directives or Step-Up Authentication don't work together over plain HTTP, running over HTTPs does seem to avoid this limitation. See also other limitations associated with Step-Up Authentication here: https://github.com/OpenIDC/mod_auth_openidc/wiki/Step-up-Authentication#limitations
Global Provider Configuration
It is not possible to specify OpenID Connect Provider and Client primitives (OIDCProvider*
/ OIDCClient*
) on a on a per-directory/location basis, those primitives are only supported on the global/vhost level. Per-location access restrictions should be handled by requesting and enforcing different scopes and claims i.e. using OIDCPathScope
/OIDCPathAuthRequestParams
, with Require claim scope:*
etc., assuming the Provider returns "scope" in the id_token
or userinfo
claims.