3d3db5d8c1
- Better handling of IDP reported errors - Better handling of session data storage size
138 lines
4.9 KiB
Diff
138 lines
4.9 KiB
Diff
diff --git a/mod_mellon2/README b/mod_mellon2/README
|
|
index 78b5f3f..eb48deb 100644
|
|
--- a/mod_mellon2/README
|
|
+++ b/mod_mellon2/README
|
|
@@ -491,6 +491,15 @@ MellonPostCount 100
|
|
# The default is that it is "Off".
|
|
# MellonPostReplay Off
|
|
|
|
+ # Page to redirect to if the IdP sends an error in response to
|
|
+ # the authentication request.
|
|
+ #
|
|
+ # Example:
|
|
+ # MellonNoSuccessErrorPage https://sp.example.org/login_failed.html
|
|
+ #
|
|
+ # The default is to not redirect, but rather send a
|
|
+ # 401 Unautorized error.
|
|
+
|
|
</Location>
|
|
|
|
|
|
diff --git a/mod_mellon2/auth_mellon.h b/mod_mellon2/auth_mellon.h
|
|
index f99cf6f..8347013 100644
|
|
--- a/mod_mellon2/auth_mellon.h
|
|
+++ b/mod_mellon2/auth_mellon.h
|
|
@@ -210,6 +210,9 @@ typedef struct am_dir_cfg_rec {
|
|
/* No cookie error page. */
|
|
const char *no_cookie_error_page;
|
|
|
|
+ /* Authorization error page. */
|
|
+ const char *no_success_error_page;
|
|
+
|
|
/* Login path for IdP initiated logins */
|
|
const char *login_path;
|
|
|
|
@@ -276,6 +279,13 @@ typedef struct am_envattr_conf_t {
|
|
|
|
extern const command_rec auth_mellon_commands[];
|
|
|
|
+typedef struct am_error_map_t {
|
|
+ int lasso_error;
|
|
+ int http_error;
|
|
+} am_error_map_t;
|
|
+
|
|
+extern const am_error_map_t auth_mellon_errormap[];
|
|
+
|
|
/* When using a value from a directory configuration structure, a special value is used
|
|
* to state "inherit" from parent, when reading a value and the value is still inherit from, it
|
|
* means that no value has ever been set for this directive, in this case, we use the default
|
|
diff --git a/mod_mellon2/auth_mellon_config.c b/mod_mellon2/auth_mellon_config.c
|
|
index 855330a..36f6b96 100644
|
|
--- a/mod_mellon2/auth_mellon_config.c
|
|
+++ b/mod_mellon2/auth_mellon_config.c
|
|
@@ -1046,6 +1046,15 @@ const command_rec auth_mellon_commands[] = {
|
|
" ha disabled cookies."
|
|
),
|
|
AP_INIT_TAKE1(
|
|
+ "MellonNoSuccessErrorPage",
|
|
+ ap_set_string_slot,
|
|
+ (void *)APR_OFFSETOF(am_dir_cfg_rec, no_success_error_page),
|
|
+ OR_AUTHCFG,
|
|
+ "Web page to display if the idp posts with a failed"
|
|
+ " authentication error. We will return a 401 Unauthorized error"
|
|
+ " if this is unset and the idp posts such assertion."
|
|
+ ),
|
|
+ AP_INIT_TAKE1(
|
|
"MellonSPMetadataFile",
|
|
am_set_filestring_slot,
|
|
(void *)APR_OFFSETOF(am_dir_cfg_rec, sp_metadata_file),
|
|
@@ -1205,6 +1214,13 @@ const command_rec auth_mellon_commands[] = {
|
|
{NULL}
|
|
};
|
|
|
|
+const am_error_map_t auth_mellon_errormap[] = {
|
|
+ { LASSO_PROFILE_ERROR_STATUS_NOT_SUCCESS, HTTP_UNAUTHORIZED },
|
|
+#ifdef LASSO_PROFILE_ERROR_REQUEST_DENIED
|
|
+ { LASSO_PROFILE_ERROR_REQUEST_DENIED, HTTP_UNAUTHORIZED },
|
|
+#endif
|
|
+ { 0, 0 }
|
|
+};
|
|
|
|
/* Release a lasso_server object associated with this configuration.
|
|
*
|
|
@@ -1264,6 +1280,7 @@ void *auth_mellon_dir_config(apr_pool_t *p, char *d)
|
|
dir->session_length = -1; /* -1 means use default. */
|
|
|
|
dir->no_cookie_error_page = NULL;
|
|
+ dir->no_success_error_page = NULL;
|
|
|
|
dir->sp_metadata_file = NULL;
|
|
dir->sp_private_key_file = NULL;
|
|
@@ -1418,6 +1435,10 @@ void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add)
|
|
add_cfg->no_cookie_error_page :
|
|
base_cfg->no_cookie_error_page);
|
|
|
|
+ new_cfg->no_success_error_page = (add_cfg->no_success_error_page != NULL ?
|
|
+ add_cfg->no_success_error_page :
|
|
+ base_cfg->no_success_error_page);
|
|
+
|
|
|
|
new_cfg->sp_metadata_file = (add_cfg->sp_metadata_file ?
|
|
add_cfg->sp_metadata_file :
|
|
diff --git a/mod_mellon2/auth_mellon_handler.c b/mod_mellon2/auth_mellon_handler.c
|
|
index 1d42fd7..1de217a 100644
|
|
--- a/mod_mellon2/auth_mellon_handler.c
|
|
+++ b/mod_mellon2/auth_mellon_handler.c
|
|
@@ -1974,6 +1974,8 @@ static int am_handle_post_reply(request_rec *r)
|
|
LassoServer *server;
|
|
LassoLogin *login;
|
|
char *relay_state;
|
|
+ am_dir_cfg_rec *dir_cfg = am_get_dir_cfg(r);
|
|
+ int i, err;
|
|
|
|
/* Make sure that this is a POST request. */
|
|
if(r->method_number != M_POST) {
|
|
@@ -2040,7 +2042,21 @@ static int am_handle_post_reply(request_rec *r)
|
|
" Lasso error: [%i] %s", rc, lasso_strerror(rc));
|
|
|
|
lasso_login_destroy(login);
|
|
- return HTTP_BAD_REQUEST;
|
|
+ err = HTTP_BAD_REQUEST;
|
|
+ for (i = 0; auth_mellon_errormap[i].lasso_error != 0; i++) {
|
|
+ if (auth_mellon_errormap[i].lasso_error == rc) {
|
|
+ err = auth_mellon_errormap[i].http_error;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (err == HTTP_UNAUTHORIZED) {
|
|
+ if (dir_cfg->no_success_error_page != NULL) {
|
|
+ apr_table_setn(r->headers_out, "Location",
|
|
+ dir_cfg->no_success_error_page);
|
|
+ return HTTP_SEE_OTHER;
|
|
+ }
|
|
+ }
|
|
+ return err;
|
|
}
|
|
|
|
/* Extract RelayState parameter. */
|