diff --git a/ChangeLog b/ChangeLog index 8aef2eee..46da42d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +09/22/2023 +- performance: store userinfo refresh interval in session to avoid parsing JSON on each request +- bump to 2.4.14.4rc4 + 09/20/2023 - performance: skip re-validating cached provider metadata - performance: use process based locking instead of global locking for Redis caching diff --git a/configure.ac b/configure.ac index 3da39ab4..1c040ca2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([mod_auth_openidc],[2.4.14.4rc3],[hans.zandbelt@openidc.com]) +AC_INIT([mod_auth_openidc],[2.4.14.4rc4],[hans.zandbelt@openidc.com]) AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION()) diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c index fa7ee4aa..d6a58d5e 100644 --- a/src/mod_auth_openidc.c +++ b/src/mod_auth_openidc.c @@ -1234,47 +1234,48 @@ static apr_byte_t oidc_refresh_claims_from_userinfo_endpoint(request_rec *r, const char *access_token = NULL; char *userinfo_jwt = NULL; - /* get the current provider info */ - if (oidc_get_provider_from_session(r, cfg, session, &provider) == FALSE) { - *needs_save = TRUE; - return FALSE; - } + /* see if we can do anything here, i.e. a refresh interval is configured */ + apr_time_t interval = oidc_session_get_userinfo_refresh_interval(r, + session); - /* see if we can do anything here, i.e. we have a userinfo endpoint and a refresh interval is configured */ - apr_time_t interval = apr_time_from_sec( - provider->userinfo_refresh_interval); + oidc_debug(r, "interval=%" APR_TIME_T_FMT, apr_time_sec(interval)); - oidc_debug(r, "userinfo_endpoint=%s, interval=%d", - provider->userinfo_endpoint_url, - provider->userinfo_refresh_interval); + if (interval > 0) { + + /* get the current provider info */ + if (oidc_get_provider_from_session(r, cfg, session, &provider) == FALSE) { + *needs_save = TRUE; + return FALSE; + } - if ((provider->userinfo_endpoint_url != NULL) && (interval > 0)) { + if (provider->userinfo_endpoint_url != NULL) { - /* get the last refresh timestamp from the session info */ - apr_time_t last_refresh = oidc_session_get_userinfo_last_refresh(r, - session); + /* get the last refresh timestamp from the session info */ + apr_time_t last_refresh = oidc_session_get_userinfo_last_refresh(r, + session); - oidc_debug(r, "refresh needed in: %" APR_TIME_T_FMT " seconds", - apr_time_sec(last_refresh + interval - apr_time_now())); + oidc_debug(r, "refresh needed in: %" APR_TIME_T_FMT " seconds", + apr_time_sec(last_refresh + interval - apr_time_now())); - /* see if we need to refresh again */ - if (last_refresh + interval < apr_time_now()) { + /* see if we need to refresh again */ + if (last_refresh + interval < apr_time_now()) { - /* get the current access token */ - access_token = oidc_session_get_access_token(r, session); + /* get the current access token */ + access_token = oidc_session_get_access_token(r, session); - /* retrieve the current claims */ - claims = oidc_retrieve_claims_from_userinfo_endpoint(r, cfg, - provider, access_token, session, NULL, &userinfo_jwt); + /* retrieve the current claims */ + claims = oidc_retrieve_claims_from_userinfo_endpoint(r, cfg, + provider, access_token, session, NULL, &userinfo_jwt); - /* store claims resolved from userinfo endpoint */ - oidc_store_userinfo_claims(r, cfg, session, provider, claims, - userinfo_jwt); + /* store claims resolved from userinfo endpoint */ + oidc_store_userinfo_claims(r, cfg, session, provider, claims, + userinfo_jwt); - /* indicated something changed */ - *needs_save = TRUE; + /* indicated something changed */ + *needs_save = TRUE; - rc = (claims != NULL); + rc = (claims != NULL); + } } } @@ -1996,6 +1997,10 @@ static apr_byte_t oidc_save_in_session(request_rec *r, oidc_cfg *c, provider->check_session_iframe); } + /* store the, possibly, provider specific userinfo_refresh_interval for performance reasons */ + oidc_session_set_userinfo_refresh_interval(r, session, + provider->userinfo_refresh_interval); + /* store claims resolved from userinfo endpoint */ oidc_store_userinfo_claims(r, c, session, provider, claims, userinfo_jwt); diff --git a/src/mod_auth_openidc.h b/src/mod_auth_openidc.h index 015eebad..693e2227 100644 --- a/src/mod_auth_openidc.h +++ b/src/mod_auth_openidc.h @@ -1007,6 +1007,8 @@ apr_time_t oidc_session_get_session_expires(request_rec *r, oidc_session_t *z); void oidc_session_set_cookie_domain(request_rec *r, oidc_session_t *z, const char *cookie_domain); const char * oidc_session_get_cookie_domain(request_rec *r, oidc_session_t *z); void oidc_session_reset_userinfo_last_refresh(request_rec *r, oidc_session_t *z); +void oidc_session_set_userinfo_refresh_interval(request_rec *r, oidc_session_t *z, const int interval); +apr_time_t oidc_session_get_userinfo_refresh_interval(request_rec *r, oidc_session_t *z); apr_time_t oidc_session_get_userinfo_last_refresh(request_rec *r, oidc_session_t *z); void oidc_session_reset_access_token_last_refresh(request_rec *r, oidc_session_t *z); apr_time_t oidc_session_get_access_token_last_refresh(request_rec *r, oidc_session_t *z); diff --git a/src/session.c b/src/session.c index 4184bbe1..d21c0b8e 100644 --- a/src/session.c +++ b/src/session.c @@ -465,6 +465,8 @@ apr_byte_t oidc_session_set(request_rec *r, oidc_session_t *z, const char *key, #define OIDC_SESSION_KEY_SESSION_STATE "ss" /* key for storing the issuer in the session context */ #define OIDC_SESSION_KEY_ISSUER "iss" +/* key for storing the provider specific user info refresh interval */ +#define OIDC_SESSION_KEY_USERINFO_REFRESH_INTERVAL "uir" /* * helper functions @@ -699,6 +701,19 @@ const char * oidc_session_get_cookie_domain(request_rec *r, oidc_session_t *z) { /* * userinfo last refresh */ + +void oidc_session_set_userinfo_refresh_interval(request_rec *r, + oidc_session_t *z, const int interval) { + oidc_session_set_timestamp(r, z, OIDC_SESSION_KEY_USERINFO_REFRESH_INTERVAL, + apr_time_from_sec(interval)); +} + +apr_time_t oidc_session_get_userinfo_refresh_interval(request_rec *r, + oidc_session_t *z) { + return oidc_session_get_key2timestamp(r, z, + OIDC_SESSION_KEY_USERINFO_REFRESH_INTERVAL); +} + void oidc_session_reset_userinfo_last_refresh(request_rec *r, oidc_session_t *z) { oidc_session_set_timestamp(r, z, OIDC_SESSION_KEY_USERINFO_LAST_REFRESH, apr_time_now());