Skip to content

Commit

Permalink
add support for OIDCPreservePostTemplates; closes #195
Browse files Browse the repository at this point in the history
to customize the POST preservation/restore process
bump to 2.4.14.4rc3

Signed-off-by: Hans Zandbelt <[email protected]>
  • Loading branch information
zandbelt committed Sep 19, 2023
1 parent f276311 commit 33a20f0
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 5 deletions.
5 changes: 4 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
- fix performance issue with latin1 encoding when using OIDCPassClaimsAs <any> latin1
- add options for authentication to OIDCOutgoingProxy; thanks @drzraf
see https://github.com/OpenIDC/mod_auth_openidc/discussions/1107
- bump to 2.4.14.4rc2
- add support for custom preserve/restore POST data templates with OIDCPreservePostTemplates
to be used when OIDCPreservePost is set to On; the hard-coded internal templates are added to
the test directory as an example; closes #195 (yeah...); thanks @kerrermanisNL and @spiazzi
- bump to 2.4.14.4rc3

09/14/2023
- fix `OIDCRefreshAccessTokenBeforeExpiry` when using it with `logout_on_error` or `authenticate_on_error`
Expand Down
8 changes: 8 additions & 0 deletions auth_openidc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,14 @@
# The default is "Off" (for security reasons). Can be configured on a per Directory/Location basis.
#OIDCPreservePost [On|Off]

# POST preserve and restore templates to be used with OIDCPreservePost
# <preserve> template needs to contain two "%s" characters
# the first for the JSON formattted POST data, the second for the URL to redirect to after preserving
# <restore> template needs to contain one "%s"
# which contains the (original) URL to POST the restored data to
# The default is to use internal templates
#OIDCPreservePostTemplates <preserve-template-filepath> <restore-template-filepath>

# Indicates whether the access token and access token expires will be passed to the application in a header/environment variable, according
# to the OIDCPassClaimsAs directive.
# Can be configured on a per Directory/Location basis. The default is "On".
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.14.4rc2],[[email protected]])
AC_INIT([mod_auth_openidc],[2.4.14.4rc3],[[email protected]])

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

Expand Down
28 changes: 28 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
#define OIDCRedisCacheConnectTimeout "OIDCRedisCacheConnectTimeout"
#define OIDCRedisCacheTimeout "OIDCRedisCacheTimeout"
#define OIDCHTMLErrorTemplate "OIDCHTMLErrorTemplate"
#define OIDCPreservePostTemplates "OIDCPreservePostTemplates"
#define OIDCDiscoverURL "OIDCDiscoverURL"
#define OIDCPassCookies "OIDCPassCookies"
#define OIDCStripCookies "OIDCStripCookies"
Expand Down Expand Up @@ -1413,6 +1414,17 @@ static const char* oidc_set_signed_jwks_uri(cmd_parms *cmd, void *m,
return NULL;
}

static const char* oidc_set_post_preserve_templates(cmd_parms *cmd, void *m,
const char *arg1, const char *arg2) {
oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
&auth_openidc_module);
if (arg1)
cfg->post_preserve_template = apr_pstrdup(cmd->pool, arg1);
if (arg2)
cfg->post_restore_template = apr_pstrdup(cmd->pool, arg2);
return NULL;
}

static const char* oidc_set_token_revocation_endpoint(cmd_parms *cmd,
void *struct_ptr, const char *args) {
oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
Expand Down Expand Up @@ -1823,6 +1835,8 @@ void* oidc_create_server_config(apr_pool_t *pool, server_rec *svr) {
c->crypto_passphrase = NULL;

c->error_template = NULL;
c->post_preserve_template = NULL;
c->post_restore_template = NULL;

c->provider.userinfo_refresh_interval =
OIDC_DEFAULT_USERINFO_REFRESH_INTERVAL;
Expand Down Expand Up @@ -2141,6 +2155,12 @@ void* oidc_merge_server_config(apr_pool_t *pool, void *BASE, void *ADD) {
c->error_template =
add->error_template != NULL ?
add->error_template : base->error_template;
c->post_preserve_template =
add->post_preserve_template != NULL ?
add->post_preserve_template : base->post_preserve_template;
c->post_restore_template =
add->post_restore_template != NULL ?
add->post_restore_template : base->post_restore_template;

c->provider_metadata_refresh_interval =
add->provider_metadata_refresh_interval
Expand Down Expand Up @@ -3625,6 +3645,14 @@ const command_rec oidc_config_cmds[] = {
(void*)APR_OFFSETOF(oidc_cfg, error_template),
RSRC_CONF,
"Name of a HTML error template: needs to contain two \"%s\" characters, one for the error message, one for the description."),
AP_INIT_TAKE2(OIDCPreservePostTemplates,
oidc_set_post_preserve_templates,
NULL,
RSRC_CONF,
"Name of POST preserve and restore templates:"
"1) preserve: needs to contain two \"%s\" characters, the first for the JSON POST data, the second for the URL to redirect to."
"2) restore: needs to contain one \"%s\", which contains the (original) URL to POST the restored data to"
),

AP_INIT_TAKE1(OIDCDiscoverURL,
oidc_set_relative_or_absolute_url_slot_dir_cfg,
Expand Down
59 changes: 56 additions & 3 deletions src/mod_auth_openidc.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ static const char* oidc_original_request_method(request_rec *r, oidc_cfg *cfg,
return method;
}

static char *post_preserve_template_contents = NULL;

/*
* send an OpenID Connect authorization request to the specified provider preserving POST parameters using HTML5 storage
*/
Expand Down Expand Up @@ -456,8 +458,33 @@ apr_byte_t oidc_post_preserve_javascript(request_rec *r, const char *location,
}
json = apr_psprintf(r->pool, "{ %s }", json);

const char *jscript = NULL;
char *template = NULL;

if (cfg->post_preserve_template != NULL) {
if (post_preserve_template_contents == NULL) {
template = oidc_util_get_full_path(r->pool,
cfg->post_preserve_template);
if (oidc_util_file_read(r, template, r->server->process->pool,
&post_preserve_template_contents) == FALSE) {
oidc_error(r, "could not read POST template: %s", template);
post_preserve_template_contents = NULL;
}
}
if (post_preserve_template_contents != NULL) {
jscript = apr_psprintf(r->pool, post_preserve_template_contents,
json,
location ?
oidc_util_javascript_escape(r->pool, location) :
"");
oidc_util_http_send(r, jscript, _oidc_strlen(jscript),
OIDC_CONTENT_TYPE_TEXT_HTML, OK);
return TRUE;
}
}

const char *jmethod = "preserveOnLoad";
const char *jscript =
jscript =
apr_psprintf(r->pool,
" <script type=\"text/javascript\">\n"
" function %s() {\n"
Expand All @@ -467,8 +494,9 @@ apr_byte_t oidc_post_preserve_javascript(request_rec *r, const char *location,
" </script>\n", jmethod, json,
location ?
apr_psprintf(r->pool, "window.location='%s';\n",
oidc_util_javascript_escape(r->pool, location)) :
"");
oidc_util_javascript_escape(r->pool,
location)) :
"");
if (location == NULL) {
if (javascript_method)
*javascript_method = apr_pstrdup(r->pool, jmethod);
Expand Down Expand Up @@ -2139,6 +2167,8 @@ static apr_byte_t oidc_handle_browser_back(request_rec *r, const char *r_state,
return FALSE;
}

static char *post_restore_template_contents = NULL;

/*
* complete the handling of an authorization response by obtaining, parsing and verifying the
* id_token and storing the authenticated user state in the session
Expand Down Expand Up @@ -2291,6 +2321,29 @@ static int oidc_handle_authorization_response(request_rec *r, oidc_cfg *c,

/* check whether form post data was preserved; if so restore it */
if (_oidc_strcmp(original_method, OIDC_METHOD_FORM_POST) == 0) {
char *template = NULL;
char *jscript = NULL;
if (c->post_restore_template != NULL) {
if (post_restore_template_contents == NULL) {
template = oidc_util_get_full_path(r->pool,
c->post_restore_template);
if (oidc_util_file_read(r, template, r->server->process->pool,
&post_restore_template_contents) == FALSE) {
oidc_error(r, "could not read POST template: %s", template);
post_restore_template_contents = NULL;
}
}
if (post_restore_template_contents != NULL) {
jscript = apr_psprintf(r->pool, post_restore_template_contents,
original_url ?
oidc_util_javascript_escape(r->pool,
original_url) :
"");
oidc_util_http_send(r, jscript, _oidc_strlen(jscript),
OIDC_CONTENT_TYPE_TEXT_HTML, OK);
return TRUE;
}
}
return oidc_request_post_preserved_restore(r, original_url);
}

Expand Down
4 changes: 4 additions & 0 deletions src/mod_auth_openidc.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ typedef struct oidc_cfg {

/* HTML to display error messages+description */
char *error_template;
/* Javascript template to preserve POST data */
char *post_preserve_template;
/* Javascript template to restore POST data */
char *post_restore_template;

/* the redirect URI as configured with the OpenID Connect OP's that we talk to */
char *redirect_uri;
Expand Down
16 changes: 16 additions & 0 deletions test/post_preserve.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Preserving...</title>
<script type="text/javascript">
function preserveOnLoad() {
sessionStorage.setItem('mod_auth_openidc_preserve_post_params', JSON.stringify(%s));
window.location='%s';
}
</script>
</head>
<body onload="preserveOnLoad()">
<p>Preserving...</p>
</body>
</html>
34 changes: 34 additions & 0 deletions test/post_restore.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Restoring...</title>
<script type="text/javascript">
function str_decode(string) {
try {
result = decodeURIComponent(string);
} catch (e) {
result = unescape(string);
}
return result;
}
function postOnLoad() {
var mod_auth_openidc_preserve_post_params = JSON.parse(sessionStorage.getItem('mod_auth_openidc_preserve_post_params'));
sessionStorage.removeItem('mod_auth_openidc_preserve_post_params');
for (var key in mod_auth_openidc_preserve_post_params) {
var input = document.createElement("input");
input.type = "hidden";
input.name = str_decode(key);
input.value = str_decode(mod_auth_openidc_preserve_post_params[key]);
document.forms[0].appendChild(input);
}
document.forms[0].action = "%s";
document.forms[0].submit();
}
</script>
</head>
<body onload="postOnLoad()">
<p>Restoring...</p>
<form method="post"></form>
</body>
</html>

0 comments on commit 33a20f0

Please sign in to comment.