DefaultCredentialHandler provides fine-grained management of credentials, it cannot
provide direct feedback to the user like presenting a warning that the current password is soon to be expired.
But, special request processing pipeline valves provided with jetspeed allow to do just that.
The configuration for these valves can be found and set in the
LoginValidationValveImpl provides feedback to the user about the cause of an failed login
It retrieves the
UserPrincipal and its current
PasswordCredential for the
specified user name, and (if found) determines an specific error code based on its state.
This error code is communicated back to through the session so an appropriate error message can be
presented to the user.
The following possible error codes can be returned (all defined in the
Of the above error codes, the
ERROR_FINAL_LOGIN_ATTEMPT will only be reported if the valve
is configured with the same
maxNumberOfAuthenticationFailures value as used for the
MaxPasswordAuthenticationFailuresInterceptor described above:
<bean id="loginValidationValve" class="org.apache.jetspeed.security.impl.LoginValidationValveImpl" init-method="initialize"> <!-- maxNumberOfAuthenticationFailures This value should be in sync with the value for org.apache.jetspeed.security.spi.impl.MaxPasswordAuthenticationFailuresInterceptor (if used) to make sense. Any value < 2 will suppress the LoginConststants.ERROR_FINAL_LOGIN_ATTEMPT error code when only one last attempt is possible before the credential will be disabled after the next authentication failure. --> <constructor-arg index="0"><value>3</value></constructor-arg> <constructor-arg index="1"> <list> <value>org.apache.jetspeed.powertool.actions</value> </list> </constructor-arg> </bean>
Along with enabling the Login Validation Valve, make sure to add the MaxPasswordAuthenticationFailuresInterceptor to the Credential Policy Manager and ensure the Login Attempts values are in sync. Out of the box, the MaxPasswordAuthenticationFailuresInterceptor is not configured.
<bean id="org.apache.jetspeed.security.spi.impl.UserPasswordCredentialPolicyManagerImpl" class="org.apache.jetspeed.security.spi.impl.UserPasswordCredentialPolicyManagerImpl"> <meta key="j2:cat" value="default or security" /> <constructor-arg index="0" ref="org.apache.jetspeed.security.CredentialPasswordEncoder" /> <constructor-arg index="1" ref="org.apache.jetspeed.security.CredentialPasswordValidator" /> <constructor-arg index="2"> <list> <!-- enforce an invalid preset password value in the persisent store is required to be changed --> <bean class="org.apache.jetspeed.security.spi.impl.ValidatePasswordOnLoadInterceptor" /> <!-- ensure preset cleartext passwords in the persistent store will be encoded on first use --> <bean class="org.apache.jetspeed.security.spi.impl.EncodePasswordOnFirstLoadInterceptor" /> <bean class="org.apache.jetspeed.security.spi.impl.MaxPasswordAuthenticationFailuresInterceptor"> <constructor-arg index="0"><value>3</value></constructor-arg> </bean> <!-- Password Expiration interceptor. Required for enabling password expirations. This example is set at 30 days --> <bean class="org.apache.jetspeed.security.spi.impl.PasswordExpirationInterceptor"> <constructor-arg index="0"><value>30</value></constructor-arg> </bean> </list> </constructor-arg> </bean>
PasswordCredentialValveImpl is meant to be used together with a special Portlet on a
special Portal Page (PSML) to automatically request or even require a user to change its password.
This valve evaluates
PasswordCredential.isUpdateRequired() and optionally the
fields to determine if a user is required or just be asked to change its password.
This valve can optionally be configured with a list of
expirationWarningDays numbers in
<bean id="passwordCredentialValve" class="org.apache.jetspeed.security.impl.PasswordCredentialValveImpl" init-method="initialize"> <constructor-arg> <!-- expirationWarningDays --> <list> <value>2</value> <value>3</value> <value>7</value> </list> </constructor-arg> </bean>
expirationDateof the password credential when a user should be warned its password is soon to expire and be asked to change it. The
previousAuthenticationDateare used to determine when this should happen. It will be done only once for each configured
expirationWarningDay. If a user logs on for the first time (after several days) with the above example configuration, 6 days before the password expires, he or she will be warned about it. And again when 3 or 2 days are left.
When a user logs on the last day before the password expires or when
true, the user will be required to change the password, regardless if expirationWarningDays
are configured or not.
To be able to automatically provide the user with this information and allow or require the password to
be changed directly after login, a special
SECURITY_LOCATOR is used. The
PageProfilerValve (which should be configed
after this valve in the pipeline) will then use this enforced locator to be used to find the
related portal page to present to the user.
For this to work, a
"security" Profiler rule must have been setup like the default one
provided by Jetspeed:
As can seen from the above image, the default page which will be presented to the user is the
/my-account.psml located in the root.
This default page contains only one portlet, the
ChangePasswordPortlet from the security
ChangePasswordPortlet works together with the
as it checks for the
PASSWORD_CREDENTIAL_DAYS_VALID_REQUEST_ATTR_KEY request parameter which will be set by
this valve with the number of days the password is still valid. For a required password change this will
be set to Integer(0).
my-account.psml page contains only the
to make sure a user which is required to change the password cannot interact with the portal any
other way then after the password is changed.
Although the user might be attempted to select a link to a different page (from a portal menu for exampl), this valve will make sure only the configured "security" locator page is returned if it is required. But, once the password is changed the then targeted page in the url will be navigated to automatically.