Skip to content

Commit

Permalink
2.4.15rc9: add (and fix) more metrics
Browse files Browse the repository at this point in the history
including provider requests, authorization and cache

Signed-off-by: Hans Zandbelt <hans.zandbelt@openidc.com>
  • Loading branch information
zandbelt committed Dec 15, 2023
1 parent 6b85189 commit 7add7d5
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 34 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
12/15/2023
- add (and fix) more metrics, including provider requests, authorization and cache
- bump to 2.4.15rc9

12/14/2023
- add metrics collection capability, configured with OIDCMetricsData and retrieved through OIDCMetricsPublish
- bump to 2.4.15rc8
Expand Down
7 changes: 5 additions & 2 deletions auth_openidc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1014,12 +1014,15 @@
# Specify metrics that you wish to collect and keep in shared memory for retrieval.
# Supported metrics classes are:
# authtype: the authentication handler type split out per AuthType: openid-connect, oauth20, auth-openidc
# redirect_uri: requests to the redirect_uri
# authn: authentication request generation and response processing
# authz: authorization errors
# requests: requests to the provider endpoints (metadata retrieval, token request, refresh requests and userinfo requests)
# session: existing session handling
# cache: cache read/write/errors
# redirect_uri: requests to the redirect_uri
# content: requests to the content handler, split out per types of request (info, metrics, jwks, etc.)
# When not defined no metrics will be recorded.
#OIDCMetricsData [ authtype | redirect_uri | authn | session | content ]+
#OIDCMetricsData [ authtype | authn | authz | requests | session | cache | redirect_uri | content ]+

# Specify the path where metrics are published and can be consumed.
# The "format=<format>" parameter can be passed to specify the format of the data.
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AC_INIT([mod_auth_openidc],[2.4.15rc8],[hans.zandbelt@openidc.com])
AC_INIT([mod_auth_openidc],[2.4.15rc9],[hans.zandbelt@openidc.com])

AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION())

Expand Down
24 changes: 18 additions & 6 deletions src/cache/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@

#include "mod_auth_openidc.h"

#include "metrics.h"

#ifdef AP_NEED_SET_MUTEX_PERMS
#include "unixd.h"
#endif
Expand Down Expand Up @@ -279,12 +281,16 @@ apr_byte_t oidc_cache_get(request_rec *r, const char *section, const char *key,
s_key = oidc_cache_get_hashed_key(r, s_secret, key);
}

OIDC_METRICS_TIMING_START(r, cfg);

/* get the value from the cache */
if (cfg->cache->get(r, section, s_key, &cache_value) == FALSE) {
rc = FALSE;
goto out;
}

OIDC_METRICS_TIMING_ADD(r, cfg, OM_CACHE_READ);

/* see if it is any good */
if ((cache_value == NULL) && (encrypted == 1) && (cfg->crypto_passphrase.secret2 != NULL)) {
oidc_debug(r, "2nd try with previous passphrase");
Expand All @@ -311,14 +317,15 @@ apr_byte_t oidc_cache_get(request_rec *r, const char *section, const char *key,
/* log the result */
msg = apr_psprintf(r->pool, "from %s cache backend for %skey %s", cfg->cache->name,
encrypted ? "encrypted " : "", key);
if (rc == TRUE)
if (rc == TRUE) {
if (*value != NULL)
oidc_debug(r, "cache hit: return %d bytes %s", *value ? (int)_oidc_strlen(*value) : 0, msg);
else
oidc_debug(r, "cache miss %s", msg);
else
} else {
OIDC_METRICS_COUNTER_INC(r, cfg, OM_CACHE_ERROR);
oidc_warn(r, "error retrieving value %s", msg);

}
return rc;
}

Expand Down Expand Up @@ -356,18 +363,23 @@ apr_byte_t oidc_cache_set(request_rec *r, const char *section, const char *key,
}
}

OIDC_METRICS_TIMING_START(r, cfg);

/* store the resulting value in the cache */
rc = cfg->cache->set(r, section, key, value, expiry);

OIDC_METRICS_TIMING_ADD(r, cfg, OM_CACHE_WRITE);

out:
/* log the result */
msg =
apr_psprintf(r->pool, "%d bytes in %s cache backend for %skey %s", (value ? (int)_oidc_strlen(value) : 0),
(cfg->cache->name ? cfg->cache->name : ""), (encrypted ? "encrypted " : ""), (key ? key : ""));
if (rc == TRUE)
if (rc == TRUE) {
oidc_debug(r, "successfully stored %s", msg);
else
} else {
OIDC_METRICS_COUNTER_INC(r, cfg, OM_CACHE_ERROR);
oidc_warn(r, "could NOT store %s", msg);

}
return rc;
}
10 changes: 9 additions & 1 deletion src/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@

#include "mod_auth_openidc.h"

#include "metrics.h"

extern module AP_MODULE_DECLARE_DATA auth_openidc_module;

#define OIDC_METADATA_SUFFIX_PROVIDER "provider"
Expand Down Expand Up @@ -663,11 +665,17 @@ apr_byte_t oidc_metadata_jwks_get(request_rec *r, oidc_cfg *cfg, const oidc_jwks
apr_byte_t oidc_metadata_provider_retrieve(request_rec *r, oidc_cfg *cfg, const char *issuer, const char *url,
json_t **j_metadata, char **response) {

OIDC_METRICS_TIMING_START(r, cfg);

/* get provider metadata from the specified URL with the specified parameters */
if (oidc_util_http_get(r, url, NULL, NULL, NULL, cfg->provider.ssl_validate_server, response,
&cfg->http_timeout_short, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL,
NULL) == FALSE)
NULL) == FALSE) {
OIDC_METRICS_COUNTER_INC(r, cfg, OM_PROVIDER_METADATA_ERROR);
return FALSE;
}

OIDC_METRICS_TIMING_ADD(r, cfg, OM_PROVIDER_METADATA);

/* decode and see if it is not an error response somehow */
if (oidc_util_decode_json_and_check_error(r, *response, j_metadata) == FALSE) {
Expand Down
71 changes: 58 additions & 13 deletions src/metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,36 @@

#define OM_CLASS_AUTH_TYPE "authtype"
#define OM_CLASS_AUTHN "authn"
#define OM_CLASS_AUTHZ "authz"
#define OM_CLASS_REQUESTS "requests"
#define OM_CLASS_SESSION "session"
#define OM_CLASS_CACHE "cache"
#define OM_CLASS_CONTENT "content"
#define OM_CLASS_REDIRECT_URI "redirect_uri"

const oidc_metrics_timing_info_t _oidc_metrics_timings_info[] = {

{ OM_AUTHN_REQUEST, OM_CLASS_AUTHN, "request",
"authentication requests" },
{ OM_AUTHN_RESPONSE, OM_CLASS_AUTHN, "response",
"authentication responses" },
{ OM_SESSION_VALID, OM_CLASS_SESSION, "valid",
"successfully validated existing sessions" },

{ OM_PROVIDER_METADATA, OM_CLASS_REQUESTS, "metadata",
"provider discovery document requests" },
{ OM_PROVIDER_TOKEN, OM_CLASS_REQUESTS, "token",
"provider token requests" },
{ OM_PROVIDER_REFRESH, OM_CLASS_REQUESTS, "refresh",
"provider refresh token requests" },
{ OM_PROVIDER_USERINFO, OM_CLASS_REQUESTS, "userinfo",
"provider userinfo requests" },

{ OM_CACHE_READ, OM_CLASS_CACHE, "read",
"cache read requests" },
{ OM_CACHE_WRITE, OM_CLASS_CACHE, "write",
"cache write requests" },

};

const oidc_metrics_counter_info_t _oidc_metrics_counters_info[] = {
Expand All @@ -72,19 +91,8 @@ const oidc_metrics_counter_info_t _oidc_metrics_counters_info[] = {
{ OM_AUTHTYPE_DECLINED, OM_CLASS_AUTH_TYPE, "handler", "declined",
"incoming requests" },

{ OM_SESSION_ERROR_COOKIE_DOMAIN, OM_CLASS_SESSION, "error", "cookie-domain",
"cookie domain validation errors for existing sessions" },
{ OM_SESSION_ERROR_EXPIRED, OM_CLASS_SESSION, "error", "expired",
"sessions that exceeded the maximum duration" },
{ OM_SESSION_ERROR_REFRESH_ACCESS_TOKEN, OM_CLASS_SESSION, "error", "refresh-access-token",
"errors refreshing the access token before expiry in existing sessions" },
{ OM_SESSION_ERROR_REFRESH_USERINFO, OM_CLASS_SESSION, "error", "refresh-user-info",
"errors refreshing claims from the userinfo endpoint in existing sessions" },
{ OM_SESSION_ERROR_GENERAL, OM_CLASS_SESSION, "error", "general",
"existing sessions that failed validation" },

{ OM_AUTHN_REQUEST_ERROR_URL, OM_CLASS_AUTHN, "request.error", "url",
"errors matching the incoming request URL against the configuration" },
{ OM_AUTHN_REQUEST_ERROR_URL, OM_CLASS_AUTHN, "request.error", "url",
"errors matching the incoming request URL against the configuration" },

{ OM_AUTHN_RESPONSE_ERROR_STATE_MISMATCH, OM_CLASS_AUTHN, "response.error", "state-mismatch",
"state mismatch errors in authentication responses" },
Expand All @@ -97,6 +105,42 @@ const oidc_metrics_counter_info_t _oidc_metrics_counters_info[] = {
{ OM_AUTHN_RESPONSE_ERROR_REMOTE_USER, OM_CLASS_AUTHN, "response.error", "remote-user",
"errors identifying the remote user based on provided claims" },

{ OM_AUTHZ_ERROR_GENERAL, OM_CLASS_AUTHZ, "error", "general",
"authorization errors" },
{ OM_AUTHZ_ACTION_AUTH, OM_CLASS_AUTHZ, "action", "auth",
"step-up authentication requests" },
{ OM_AUTHZ_ACTION_401, OM_CLASS_AUTHZ, "action", "401",
"401 authorization errors" },
{ OM_AUTHZ_ACTION_403, OM_CLASS_AUTHZ, "action", "403",
"403 authorization errors" },
{ OM_AUTHZ_ACTION_302, OM_CLASS_AUTHZ, "action", "302",
"302 authorization errors" },
{ OM_AUTHZ_ERROR_OAUTH20, OM_CLASS_AUTHZ, "error", "oauth20",
"AuthType oauth20 authorization errors 401" },

{ OM_PROVIDER_METADATA_ERROR, OM_CLASS_REQUESTS, "provider.metadata", "error"
"errors retrieving provider discovery document" },
{ OM_PROVIDER_TOKEN_ERROR, OM_CLASS_REQUESTS, "provider.token", "error",
"errors making a token request to the provider" },
{ OM_PROVIDER_REFRESH_ERROR, OM_CLASS_REQUESTS, "provider.refresh", "error",
"errors refreshing the access token" },
{ OM_PROVIDER_USERINFO_ERROR, OM_CLASS_REQUESTS, "provider.userinfo", "error",
"errors calling the provider userinfo endpoint" },

{ OM_SESSION_ERROR_COOKIE_DOMAIN, OM_CLASS_SESSION, "error", "cookie-domain",
"cookie domain validation errors for existing sessions" },
{ OM_SESSION_ERROR_EXPIRED, OM_CLASS_SESSION, "error", "expired",
"sessions that exceeded the maximum duration" },
{ OM_SESSION_ERROR_REFRESH_ACCESS_TOKEN, OM_CLASS_SESSION, "error", "refresh-access-token",
"errors refreshing the access token before expiry in existing sessions" },
{ OM_SESSION_ERROR_REFRESH_USERINFO, OM_CLASS_SESSION, "error", "refresh-user-info",
"errors refreshing claims from the userinfo endpoint in existing sessions" },
{ OM_SESSION_ERROR_GENERAL, OM_CLASS_SESSION, "error", "general",
"existing sessions that failed validation" },

{ OM_CACHE_ERROR, OM_CLASS_CACHE, "cache", "error",
"cache read/write errors" },

{ OM_REDIRECT_URI_AUTHN_RESPONSE_REDIRECT, OM_CLASS_REDIRECT_URI, "authn.response", "redirect",
"authentication responses received in a redirect", },
{ OM_REDIRECT_URI_AUTHN_RESPONSE_POST, OM_CLASS_REDIRECT_URI, "authn.response", "post",
Expand Down Expand Up @@ -138,6 +182,7 @@ const oidc_metrics_counter_info_t _oidc_metrics_counters_info[] = {
"HTTP POST preservation requests to the content handler" },
{ OM_CONTENT_REQUEST_UNKNOWN, OM_CLASS_CONTENT, "request", "unknown",
"unknown requests to the content handler" },

};

// clang-format on
Expand Down
38 changes: 31 additions & 7 deletions src/metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,17 @@ apr_status_t oidc_metrics_cache_child_init(apr_pool_t *p, server_rec *s);
apr_status_t oidc_metrics_cache_cleanup(server_rec *s);
int oidc_metrics_handle_request(request_rec *r);

typedef enum { OM_AUTHN_REQUEST = 0, OM_AUTHN_RESPONSE, OM_SESSION_VALID } oidc_metrics_timing_type_t;
typedef enum {
OM_AUTHN_REQUEST = 0,
OM_AUTHN_RESPONSE,
OM_SESSION_VALID,
OM_PROVIDER_METADATA,
OM_PROVIDER_TOKEN,
OM_PROVIDER_REFRESH,
OM_PROVIDER_USERINFO,
OM_CACHE_READ,
OM_CACHE_WRITE,
} oidc_metrics_timing_type_t;

typedef struct oidc_metrics_timing_info_t {
oidc_metrics_timing_type_t type;
Expand Down Expand Up @@ -80,12 +90,6 @@ typedef enum {
OM_AUTHTYPE_AUTH_OPENIDC,
OM_AUTHTYPE_DECLINED,

OM_SESSION_ERROR_COOKIE_DOMAIN,
OM_SESSION_ERROR_EXPIRED,
OM_SESSION_ERROR_REFRESH_ACCESS_TOKEN,
OM_SESSION_ERROR_REFRESH_USERINFO,
OM_SESSION_ERROR_GENERAL,

OM_AUTHN_REQUEST_ERROR_URL,

OM_AUTHN_RESPONSE_ERROR_STATE_MISMATCH,
Expand All @@ -94,6 +98,26 @@ typedef enum {
OM_AUTHN_RESPONSE_ERROR_PROTOCOL,
OM_AUTHN_RESPONSE_ERROR_REMOTE_USER,

OM_AUTHZ_ERROR_GENERAL,
OM_AUTHZ_ACTION_AUTH,
OM_AUTHZ_ACTION_401,
OM_AUTHZ_ACTION_403,
OM_AUTHZ_ACTION_302,
OM_AUTHZ_ERROR_OAUTH20,

OM_PROVIDER_METADATA_ERROR,
OM_PROVIDER_TOKEN_ERROR,
OM_PROVIDER_REFRESH_ERROR,
OM_PROVIDER_USERINFO_ERROR,

OM_SESSION_ERROR_COOKIE_DOMAIN,
OM_SESSION_ERROR_EXPIRED,
OM_SESSION_ERROR_REFRESH_ACCESS_TOKEN,
OM_SESSION_ERROR_REFRESH_USERINFO,
OM_SESSION_ERROR_GENERAL,

OM_CACHE_ERROR,

OM_REDIRECT_URI_AUTHN_RESPONSE_REDIRECT,
OM_REDIRECT_URI_AUTHN_RESPONSE_POST,
OM_REDIRECT_URI_AUTHN_RESPONSE_IMPLICIT,
Expand Down
Loading

0 comments on commit 7add7d5

Please sign in to comment.