Files
FreshRSS/Docker/FreshRSS.Apache.conf
T
CronandAlexandre Alapetite 09478222ce Docker/OIDC: redirect to a default URL on expired auth state instead of 400-ing (#9143)
## Problem

With OIDC on the official Docker image, interactive SSO logins intermittently return `HTTP 400` at the `/i/oidc/` callback. The failure tracks login duration. `mod_auth_openidc` sets an anti-CSRF state cookie bounded by `OIDCStateTimeout` (default 300 s). If a login through an external IdP takes longer than that (MFA, a slow provider screen, the user stepping away), the cookie is already gone when the callback returns. The image does not set `OIDCDefaultURL`, so the module has no fallback and returns an error instead of restarting the login.

Apache log:

```
oidc_response_proto_state_restore: state has expired
oidc_response_process: invalid authorization response state and
        no default SSO URL is set, sending an error...
→ GET /i/oidc/?code=…&state=… 400
```

This is [documented mod_auth_openidc behaviour](https://github.com/OpenIDC/mod_auth_openidc/blob/72c9f479c2d228477ff0a9518964f61879c83fb6/auth_openidc.conf#L723-L733) when `OIDCDefaultURL` is unset. Both `OIDCDefaultURL` and `OIDCStateTimeout` are `RSRC_CONF` (server config only), so the `./FreshRSS/p/i/.htaccess` escape hatch cannot set them and the fix has to live in the image.

Reproduce: log out, start SSO, wait more than 5 minutes on the IdP screen, complete.

## Fix

Add `OIDC_DEFAULT_URL`, wired through the existing `${OIDC_*}` env pattern, defaulting to `/i/` (the index, consistent with `OIDCRedirectURI /i/oidc/`). On an expired or unmatchable state the module now redirects to `/i/`, which is protected and starts a fresh login against the existing IdP session. `OIDCStateTimeout` stays at 300 s; the window is fine, the missing fallback was the bug.

`OIDC_STATE_TIMEOUT` is intentionally not exposed. It can be added the same way if there is a reason to tune the window.

* Docker/OIDC: redirect to a default URL on expired auth state instead of 400-ing

Adds OIDC_DEFAULT_URL (default /i/), wired through the existing ${OIDC_*} env
pattern, so an expired or unmatchable mod_auth_openidc state redirects to the
FreshRSS index and restarts the login instead of returning HTTP 400.

* git commit update

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-24 17:55:36 +02:00

98 lines
3.0 KiB
Plaintext

ServerName freshrss.localhost
Listen 80
DocumentRoot /var/www/FreshRSS/p/
AllowEncodedSlashes On
ServerTokens OS
TraceEnable Off
ErrorLog /dev/stderr
# For logging the original user-agent IP instead of proxy IPs:
<IfModule mod_remoteip.c>
# Can be disabled by setting the TRUSTED_PROXY environment variable to 0:
RemoteIPHeader X-Forwarded-For
# Can be overridden by the TRUSTED_PROXY environment variable:
RemoteIPInternalProxy 10.0.0.1/8 172.16.0.1/12 192.168.0.1/16
</IfModule>
# Default, will be overridden by p/.htaccess and p/api/.htaccess
SetEnvIfExpr "reqenv('LOG_REMOTE_USER') == ''" LOG_REMOTE_USER=-
SetEnvIfExpr "reqenv('LOG_REMOTE_USER') == '-' && reqenv('REMOTE_USER') =~ /(.+)/" LOG_REMOTE_USER=$1
LogFormat "%a %l %{LOG_REMOTE_USER}e %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_proxy
CustomLog "|/var/www/FreshRSS/cli/sensitive-log.sh" combined_proxy
<IfDefine OIDC_ENABLED>
<IfModule !auth_openidc_module>
Error "The auth_openidc_module is not available. Install it or unset environment variable OIDC_ENABLED."
</IfModule>
# Workaround to be able to check whether an environment variable is set
# See: https://serverfault.com/questions/1022233/using-ifdefine-with-environment-variables/1022234#1022234
Define VStart "${"
Define VEnd "}"
OIDCProviderMetadataURL ${OIDC_PROVIDER_METADATA_URL}
OIDCClientID ${OIDC_CLIENT_ID}
OIDCClientSecret ${OIDC_CLIENT_SECRET}
OIDCSessionInactivityTimeout ${OIDC_SESSION_INACTIVITY_TIMEOUT}
OIDCSessionMaxDuration ${OIDC_SESSION_MAX_DURATION}
OIDCSessionType ${OIDC_SESSION_TYPE}
OIDCRedirectURI /i/oidc/
OIDCDefaultURL ${OIDC_DEFAULT_URL}
OIDCCryptoPassphrase ${OIDC_CLIENT_CRYPTO_KEY}
Define "Test_${OIDC_REMOTE_USER_CLAIM}"
<IfDefine Test_${VStart}OIDC_REMOTE_USER_CLAIM${VEnd}>
OIDCRemoteUserClaim preferred_username
</IfDefine>
<IfDefine !Test_${VStart}OIDC_REMOTE_USER_CLAIM${VEnd}>
OIDCRemoteUserClaim "${OIDC_REMOTE_USER_CLAIM}"
</IfDefine>
Define "Test_${OIDC_SCOPES}"
<IfDefine Test_${VStart}OIDC_SCOPES${VEnd}>
OIDCScope openid
</IfDefine>
<IfDefine !Test_${VStart}OIDC_SCOPES${VEnd}>
OIDCScope "${OIDC_SCOPES}"
</IfDefine>
Define "Test_${OIDC_X_FORWARDED_HEADERS}"
<IfDefine !Test_${VStart}OIDC_X_FORWARDED_HEADERS${VEnd}>
OIDCXForwardedHeaders ${OIDC_X_FORWARDED_HEADERS}
</IfDefine>
# Additional parameters can be set e.g. in /var/www/FreshRSS/p/i/.htaccess
</IfDefine>
<Directory />
AllowOverride None
Options FollowSymLinks
Require all denied
</Directory>
<Directory /var/www/FreshRSS/p>
AllowOverride None
Include /var/www/FreshRSS/p/.htaccess
Options FollowSymLinks
Require all granted
</Directory>
<Directory /var/www/FreshRSS/p/api>
Include /var/www/FreshRSS/p/api/.htaccess
</Directory>
<Directory /var/www/FreshRSS/p/i>
ExpiresActive Off
<IfDefine OIDC_ENABLED>
AuthType openid-connect
Require valid-user
</IfDefine>
IncludeOptional /var/www/FreshRSS/p/i/.htaccess
</Directory>
<Directory /var/www/FreshRSS/p/themes>
Include /var/www/FreshRSS/p/themes/.htaccess
</Directory>