From: Timo Sirainen Date: Fri, 15 Aug 2025 10:36:08 +0000 (+0300) Subject: lib-oauth2, oauth2: Add oauth2_token_expire_grace setting X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=76dbb7ecd8da0472dc4e154199be4a098e7c5dd5;p=thirdparty%2Fdovecot%2Fcore.git lib-oauth2, oauth2: Add oauth2_token_expire_grace setting --- diff --git a/src/auth/db-oauth2.c b/src/auth/db-oauth2.c index 230c6cf767..5aa9d0d387 100644 --- a/src/auth/db-oauth2.c +++ b/src/auth/db-oauth2.c @@ -21,6 +21,8 @@ #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("oauth2_"#name, name, struct auth_oauth2_settings) +#define DEF_SECS(type, name) \ + SETTING_DEFINE_STRUCT_##type("oauth2_"#name, name##_secs, struct auth_oauth2_settings) static const struct setting_define auth_oauth2_setting_defines[] = { DEF(STR, tokeninfo_url), @@ -36,6 +38,7 @@ static const struct setting_define auth_oauth2_setting_defines[] = { DEF(STR, client_secret), DEF(BOOLLIST, issuers), DEF(STR, openid_configuration_url), + DEF_SECS(TIME, token_expire_grace), DEF(BOOL, force_introspection), DEF(BOOL, send_auth_headers), DEF(BOOL, use_worker_with_mech), @@ -60,6 +63,7 @@ static const struct auth_oauth2_settings auth_oauth2_default_settings = { .client_secret = "", .issuers = ARRAY_INIT, .openid_configuration_url = "", + .token_expire_grace_secs = 60, .send_auth_headers = FALSE, .use_worker_with_mech = FALSE, }; @@ -195,6 +199,7 @@ static int db_oauth2_setup(struct db_oauth2 *db, const char **error_r) db->oauth2_set.client_id = db->set->client_id; db->oauth2_set.client_secret = db->set->client_secret; db->oauth2_set.send_auth_headers = db->set->send_auth_headers; + db->oauth2_set.token_expire_grace_secs = db->set->token_expire_grace_secs; if (!array_is_empty(&db->set->scope)) { db->oauth2_set.scope = p_array_const_string_join(db->pool, &db->set->scope, " "); diff --git a/src/auth/db-oauth2.h b/src/auth/db-oauth2.h index 3f362c61dd..9ebc0a4823 100644 --- a/src/auth/db-oauth2.h +++ b/src/auth/db-oauth2.h @@ -43,6 +43,10 @@ struct auth_oauth2_settings { */ const char *openid_configuration_url; + /* How many seconds after token expiration is it still allowed to + succeed the authentication. */ + unsigned int token_expire_grace_secs; + /* Should introspection be done even if not necessary */ bool force_introspection; /* Should we send service and local/remote endpoints as X-Dovecot-Auth headers */ diff --git a/src/lib-oauth2/oauth2-jwt.c b/src/lib-oauth2/oauth2-jwt.c index 357b92fca2..8ccff8ca14 100644 --- a/src/lib-oauth2/oauth2-jwt.c +++ b/src/lib-oauth2/oauth2-jwt.c @@ -514,10 +514,12 @@ oauth2_jwt_body_process(const struct oauth2_settings *set, iat, t0 + 1); return -1; } - if (exp < t0) { + /* Allow using slightly expired token, in case client time isn't well + synced. */ + if (exp < t0 - set->token_expire_grace_secs) { *error_r = t_strdup_printf( - "Token has expired (exp=%"PRId64" < %"PRId64")", - exp, t0); + "Token has expired (exp=%"PRId64" < %"PRId64" - grace %u)", + exp, t0, set->token_expire_grace_secs); return -1; } diff --git a/src/lib-oauth2/oauth2.h b/src/lib-oauth2/oauth2.h index 9b25ea52f7..aadae4a90b 100644 --- a/src/lib-oauth2/oauth2.h +++ b/src/lib-oauth2/oauth2.h @@ -38,6 +38,9 @@ struct oauth2_settings { struct oauth2_validation_key_cache *key_cache; /* valid issuer names */ const char *const *issuers; + /* How many seconds after token expiration is it still allowed to + succeed the authentication. */ + unsigned int token_expire_grace_secs; enum { INTROSPECTION_MODE_GET_AUTH,