The Shibboleth IdP V4 software has reached its End of Life and is no longer supported. This documentation is available for historical purposes only. See the IDP5 wiki space for current documentation on the supported version.
The authn/Password login flow supports an extensible set of back-ends for password-based authentication, normally collected using a web form, and is the flow used at least in part by most deployments.
It is compatible with non-browser clients by virtue of supporting HTTP Basic authentication if credentials are provided without prompting, and knows not to present a form when a non-browser profile like ECP is used.
New to V4 is a refactored design that includes a dedicated plugin API for developing custom "back-ends", the CredentialValidator interface and some associated base classes for assisting in developing new ones. The flow now also supports chaining of CredentialValidator plugins in arbitrary sequences instead of requiring the use of JAAS login modules for that feature.
Enabling Module (V4.1+)
For V4.1+, configuring and using this feature requires that you first enable the "idp.authn.Password" module if it isn't already enabled. Systems upgraded from older releases generally come pre-enabled due to the prior state of the configuration tree.
Use authn/password-authn-config.xml to configure the main features of this flow.
Unlike V3, it is no longer necessary to pick a single back-end configuration and to comment or uncomment specific supporting files for LDAP, Kerberos, or JAAS. All of the files can be imported if desired/needed and any of the back-ends can be used at the same time in sequence, if desired.
Most features of this flow can be configured with authn/authn.properties, with some advanced features relying on authn/password-authn-config.xml.
Unlike V3, it is no longer necessary to pick a single back-end configuration and to comment or uncomment specific supporting files for LDAP, Kerberos, or JAAS. All of the original back-end files have been removed from the default distribution and any outlying needs for XML configuration can be placed in authn/password-authn-config.xml.
For detailed information on configuring the supplied back-ends, see:
Aside from the more specific back-end configurations, there are beans and properties defined for some general configuration independent of the back-end chosen. They are all listed in the reference section below.
The most important bean is shibboleth.authn.Password.Validators, a List of CredentialValidator plugins that should be used to validate the subject's username and password.
An Boolean bean called shibboleth.authn.Password.RequireAll controls whether the credentials must be validated successfully by all applicable plugins in the list, or just one.
Combining plugins tends to be more complex but the default, requiring only a single valid result, is fairly simple to deal with. One obvious issue is that you should make sure to set the shibboleth.authn.Password.RemoveAfterValidation bean to FALSE if you apply the "require all" mode to prevent the username/password information from being pulled mid-request.
A property named idp.authn.Password.requireAll controls whether the credentials must be validated successfully by all applicable plugins in the list, or just one.
Combining plugins tends to be more complex but the default, requiring only a single valid result, is fairly simple to deal with. One obvious issue is that you should make sure to set the property named idp.authn.Password.removeAfterValidation to false if you apply the "require all" mode to prevent the username/password information from being pulled mid-request.
Upgraded V3 Configurations
For backward compatibility, the original "one back-end at a time" configuration is detected and turned into a list of a single CredentialValidator plugin that matches as much as possible the behavior of the original software. This is triggered by the absence of the new shibboleth.authn.Password.Validators bean and the presence of the old "ValidateUsernamePassword" bean alias that was used in V3 to identify which back-end to use.
Basic Features
The first user interface layer of the flow is actually HTTP Basic authentication; if a header with credentials is supplied, the credentials are tested immediately with no prompting. If that step fails, or no credentials are supplied, then a view is rendered unless the request is for passive authentication or part of a non-browser profile.
Views are handled by Spring Web Flow, so support various technologies, but Velocity and JSP are supported by default and the examples are all based on Velocity.
Be aware that the default view templates and configuration of classified messages (see later section on Errors and Warnings) results in a system that will report context-sensitive errors to the user, such as whether the password was invalid or the username was mis-entered. This is appropriate for most organizations to reduce help desk calls caused by simple user error, but some organizations keep usernames a secret and may wish to adjust the configuration to collapse all error reporting and avoid leaking information about whether usernames are valid or not.
Example Velocity User Interface
The example Velocity templates views/login.vm and views/login-error.vm illustrate generally how to populate the form, and how to detect and respond to error conditions. Internationalization is performed through the use of Spring message properties (which can be overridden via the top-level messages folder). Information on Spring internationalization is near the end of this section of the Spring documentation.
When rendering Velocity views, several variables are available to aid per-relying party customization.
Spring form generation macros such as #springMessage and #springMessageText are available to Velocity templates.
You can freely comment out or remove the "Do Not Cache" support of course, or use Javascript to automate it for certain address ranges.
Advanced Error Handling Example
The error message classification feature allows error messages to be mapped into grouped "classes" of errors that can be used in the view to report the results of a failed login. The main value of this feature is in supporting chains of multiple validators because the system will accumulate all of the classified errors that occur so that a precedence of error types can be applied to decide what to report to the user. A working example of this:
views/login-error.vm
## Velocity Template for login error message production, included by login.vm
##
## authenticationErrorContext - context containing error data, if available
##
#if ($authenticationErrorContext && $authenticationErrorContext.getClassifiedErrors().size() > 0 && $authenticationErrorContext.getClassifiedErrors().iterator().next() != "ReselectFlow")
## This handles errors that are classified by the message maps in the config.
#if ($authenticationErrorContext.getClassifiedErrors().contains("InvalidPassword"))
#set ($eventId = "InvalidPassword")
#elseif ($authenticationErrorContext.getClassifiedErrors().contains("AccountLocked"))
#set ($eventId = "AccountLocked")
#elseif ($authenticationErrorContext.getClassifiedErrors().contains("AccountDisabled"))
#set ($eventId = "AccountDisabled")
#elseif ($authenticationErrorContext.getClassifiedErrors().contains("ExpiredPassword"))
#set ($eventId = "ExpiredPassword")
#elseif ($authenticationErrorContext.getClassifiedErrors().contains("UnknownUsername"))
#set ($eventId = "UnknownUsername")
#end
#elseif ($authenticationErrorContext && $authenticationErrorContext.getExceptions().size() > 0)
## This handles login exceptions that are left unclassified.
#set ($loginException = $authenticationErrorContext.getExceptions().get(0))
#if ($loginException.getMessage())
#set ($message = "Login Failure: $loginException.getMessage()")
#else
#set ($message = "Unidentified error")
#end
#end
#if ($eventId || $message)
<div class="error notification">
#if ($eventId == "AccountLocked")
## your code here
#elseif ($eventId == "AccountDisabled")
## your code here
#elseif ($eventId == "ExpiredPassword")
## your code here
#elseif ($eventId == "InvalidPassword")
## your code here
#elseif ($eventId == "UnknownUsername")
## your code here
#elseif ($message)
## your code here
#end
</div>
#end
JSP User Interface
The use of JSP is not advised, but is supported. To do so, views/login.vm must be removed or renamed and the IdP restarted, or it will take precedence. Views in JSP should be created in edit-webapp/WEB-INF/jsp (and the warfile should be recreated with bin/build.sh or bin/build.bat and the container restarted). The old V2 Taglibs are supported for JSP for now, but we have plans to deprecate them in the future.
Advanced Features
Reference
Notes
The shibboleth.authn.Password.RetainAsPrivateCredential bean (and idp.authn.Password.retainAsPrivateCredential property in V4.1+) should be used with caution, as it retains the password and makes it available in plaintext form within server memory at various stages. When the session is written to storage, the password is encrypted with the secret key used by the IdP for other encryption of data to itself, but it will be decrypted and back in memory at various times when the session is accessed or updated.