SAF Expired Password Information¶
Related Links¶
z/OS Questions¶
Information related to IHS on z/OS can be found in the z/OS questions page.
Known Issues with Updating SAF Password via the AuthSAFExpiration Directive¶
Users of mod_authnz_saf are only affected by these issues when the
AuthSAFExpiration
or AuthSAFReEnter
directives are set. For those looking
for an alternative way to notify users of their password expiration, please
look at AuthSAFExpiredRedirect
directive or using form-based authentication instead.
Chrome does not display the expired password realm message¶
After Chrome 49, Chrome no longer displays a basic realm message in their basic authentication prompt. This change prevents mod_authnz_saf from notifying users that their SAF password has expired since mod_authnz_saf appends the expired message to the realm message. Issue 602301 was opened to track this issue. The issue is still present in Chrome as of version 58.0.3029.110.
Firefox issues several authentication requests after user is prompted to update SAF password¶
When a user provides credentials for basic authentication, Firefox will cache the credentials and provide them automatically for authentication requests with the same realm. This has been found to cause issues where Firefox will repeatedly respond to 401 responses with the cached credentials until Firefox finally gives up. This can result in increased CPU usage and cause a lot of output to be written to the logs. It can also cause a user account to be revoked after too many unsuccessful authentication attempts.
A particular scenario where this is an issue is when a user attempts to access a page that requires authentication and their credentials have expired:
The user makes a request that requires authentication. mod_authnz_saf responds with a 401 with the realm message "SAF Basic Authentication".
The user provides their credentials that happen to be expired which are now cached by Firefox. mod_authnz_saf responds with another 401, but this time with "Expired ! oldpw/newpw/newpw" appended to the original realm.
The user provides invalid credentials to which Firefox caches for the expired realm message. mod_authnz_saf fails to authenticate the user with the invalid credentials and responds with yet another 401 response with the original realm message.
Firefox provides the valid but expired cached credentials for the original realm. mod_authnz_saf subsequently responds with another 401 with the expired message realm to let the user know to update their password.
Firefox sees the expired message realm and responds by providing the incorrect cached credentials. This cycles repeats until Firefox eventually gives up and clears the cached credentials.
See Firefox Bug 201620 for more information.
Expired Password Loop Mitigation¶
To mitigate the number of authentication requests that hit the server, the
session cookie saf_auth_limit
was introduced. The cookie is added on the first
expired password update request and is decremented for each subsequent expired
password update request. Once the expired password update request limit has
been reached (2 by default), a 403 Forbidden will be returned, stopping
Firefox from sending any more authentication requests using cached credentials.
This feature is available in fixpacks 9.0.0.5, 8.5.5.12, 8.0.0.14, 7.0.0.45 and
above.
The 403 error page will display general instructions that the user can follow
to successfully update their password. Furthermore, a custom message
(either text or HTML) can be added to the error page to provide or link to
additional information using the AuthSAFUpdateFailedMessage
directive.
The environment variable SAF_AUTH_LIMIT
was added to change the limit of
expired password update requests that is allowed before a 403 occurs. By
setting the environment variable SAF_AUTH_LIMIT
to -1, this feature can be
disabled entirely. A few examples are provided below.
# Increase the limit of expired password update requests allowed for Firefox user agents
BrowserMatch Firefox SAF_AUTH_LIMIT=3
# Disable this feature for all browsers except Firefox
BrowserMatch . SAF_AUTH_LIMIT=-1
BrowserMatch Firefox SAF_AUTH_LIMIT=2
# Disable this feature entirely
BrowserMatch . SAF_AUTH_LIMIT=-1
Using AuthSAFExpiredRedirect instead of AuthSAFExpiration¶
It is suggested that the SAF password update via AuthSAFExpiration
not be
used as there are usability issues with both Chrome and Firefox.
AuthSAFExpiration
can be disabled by commenting or removing the following
directives from the httpd configuration file:
# Remove these lines from the configuration
AuthSAFExpiration custom-text
AuthSAFReEnter custom-text
Informing users that their SAF password has expired can be done by redirecting to an error page defined by the AuthSAFExpiredRedirect directive. An example of such a configuration is as follows:
<Location "/saf_protected/">
AuthName "SAF Basic Authentication"
AuthType Basic
AuthBasicProvider saf
Require valid-user
AuthSAFExpiredRedirect /error/saf_expired.html
</Location>
It is also important to verify that the redirect target is not protected! If the error page is protected, it can be unprotected using one of the following stanzas:
# IHS 9.0 and above
<IfModule authn_core_module>
<Location "/error">
Require all granted
</Location>
</IfModule>
# IHS 8.0 and 8.5.5
<IfModule authz_default_module>
<Location "/error">
Order allow,deny
Allow from all
Satisfy any
</Location>
</IfModule>
Form-Based SAF Password Update Utility¶
A feature has been added with PI81602 to allow users to update their passwords using a form. It also allows users to use a custom form instead of the default form that mod_authnz_saf provides. PI81602 is targeted for IBM HTTP Server fixpacks: 9.0.0.5, 8.5.5.12, 8.0.0.14, and 7.0.0.45.
The feature can be enabled by adding the mod_authnz_saf handler saf-change-pw
and redirecting to the handler when a user's password has expired using the
AuthSAFExpiredForm
directive. A basic configuration will look similar to the
following stanza:
# Enable and configure the mod_authnz_saf module
LoadModule authnz_saf_module modules/mod_authnz_saf.so
<Location "/saf_protected/">
AuthName "SAF Basic Authentication"
AuthType Basic
AuthBasicProvider saf
Require valid-user
# Redirect to the saf-change-pw handler to handle expired passwords.
AuthSAFExpiredForm /change-saf-password
</Location>
# Enable the saf-change-pw handler. It is important to make sure this location
# is not protected! An example of un-protecting a certain location is given
# in the previous section.
<Location "/change-saf-password">
SetHandler saf-change-pw
# The IBM-1047 character set encoding is required if using the default form provided
# by the handler. This is to make sure the correct encoding is set in case the user
# switches CharsetSourceEnc to a value other than IBM-1047.
CharsetSourceEnc IBM-1047
# This option is required so that the handler is able to read the request body. This
# needs to be set in case the translation of request bodies was disabled in a more
# generic context (e.g. virtual host, server, etc).
CharsetOptions TranslateRequestBodies
</Location>
Using a Custom SAF Password Update Form¶
Using a custom form page [example] is also an option instead of using the default one. There are certain requirements that must be followed, however, so that mod_authnz_saf can process the form's data:
The form content type must be
application/x-www-form-urlencoded
.The form must post to the
saf-change-pw
handler defined in the httpd configuration.There must be a user name field named
user
.There must be a password field named
old_password
.There must be a password field named
new_password
.There must be a password field named
confirm_new_password
.There must be a hidden input field named
original_uri
whose value should be set to the the valueuri
passed in via the query string. See the link to the example HTML form above.
Errors are passed back as an ID to the client using the query string variable
error
. The list of error IDs and their meanings can be found in the linked
example form above.
The custom form page can be enabled by telling mod_authnz_saf to redirect to it
when an expired password is found using the AuthSAFExpiredForm
directive:
# Enable and configure the mod_authnz_saf module
LoadModule authnz_saf_module modules/mod_authnz_saf.so
<Location "/saf_protected/">
AuthName "SAF Basic Authentication"
AuthType Basic
AuthBasicProvider saf
Require valid-user
# Redirect to the custom form page to handle expired passwords.
AuthSAFExpiredForm /my-custom-form.html
</Location>
# Make sure the expired form is not protected.
<Location "/my-custom-form.html">
Require all granted
</Location>
# Enable the saf-change-pw handler. It is important to make sure this location
# also is not protected.
<Location "/change-saf-password">
SetHandler saf-change-pw
Require all granted
</Location>
Avoid Trouble when using a Custom Expired Form¶
The location you select to set the
saf-change-pw
handler on (i.e.,change-saf-password
from example above) should not represent any path on disk.The custom form must NOT have the same prefix as the password change handler, e.g.,
/change-saf-password/my-custom-form.html
.After PH35356, users will no longer receive a reason for why the password update failed by default. This behavior now requires
AuthSAFErrorReason ON
to be set in the global server configuration to be enabled.If you use the example
saf-password-change.txt
provided above, you will need to make the following changes:Update the extension from
.txt
to.html
If you used a different location for your SAF change password handler, then you will also need to update the form's
action
attribute to point to the correct location.