Current File(s): conf/authn/password-authn-config.xml, views/login.vm, conf/authn/authn.properties (V4.1+)
Format: Native Spring
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.
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.
(Windows) C:\opt\shibboleth-idp> bin\module.bat -t idp.authn.Password || bin\module.bat -e idp.authn.Password (Other) $ bin/module.sh -t idp.authn.Password || bin/module.sh -e idp.authn.Password |
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. |
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.
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.
Example Velocity User InterfaceThe 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 ExampleThe 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
JSP User InterfaceThe 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. |
There are parent beans defined for each back-end plugin supported to allow easy incorporation of the default configured behavior into the chain of validators. The settings inherited from V3 and (prior to V4.1) defined in the individual Spring bean files are now "global" options for each back-end that will apply to any validator of the given type unless overridden. For example, this syntax defines a single LDAP validator that uses settings defined in a manner consistent with older versions of the software. The parent bean is used "as is" with no changes.
This syntax in contrast uses the parent bean as a template:
In this case, the LDAP authenticator object used is explicitly set to the bindSearchAuthenticator bean from the old V3 version of ldap-authn-config.xml instead of the value set by the "idp.authn.LDAP.authenticator" property. This is a simple example but the point is that once you switch from a |
With the expansion from one to potentially multiple back-end validators, a backward-compatible enhancement has been made to the support for case folding, trimming, and regular expression transformation of the username entered by a subject. Instead of normalizing the value "in place", the same features can be applied either globally or individually to each validator so that the normalized value may be different in each case. The globally defined beans (and properties in V4.1) are used if not overridden, but options exist on each supported CredentialValidator class to override a global setting with a more specific setting. Note that the result of a successful authentication via a particular validator will typically produce a Java Subject containing a UsernamePrincipal containing the normalized value specific to that validator, so it's possible when chaining and using the "RequireAll" feature to produce compound results containing multiple, distinct UsernamePrincipal objects that will not work with the default/simple SimplePostLoginC14NConfiguration used in many cases. Something more may be needed to tell the system which of the potentially multiple "usernames" should be the official one used in the session. Similarly, the bean shibboleth.authn.Password.matchExpression (V4.0) or property idp.authn.Password.matchExpression (V4.1+) are applied globally, if set, but each CredentialValidator can be individually configured with their own
|
A special feature of this flow is the ability to inject your own behavior in response to particular error or warning conditions that occur. These conditions are set via the shibboleth.authn.Password.ClassifiedMessageMap bean in authn/password-authn-config.xml. If you map a particular string label to one or more exception/error messages in the map, that string label becomes a flow "event" that you can program the flow to respond to. If your goal is to terminate processing at this point, then you should take a look at the discussion in AuthenticationConfiguration under "Custom Events", which describes how to configure the system to treat your custom events as allowable "end" states for the request and handle them as errors. If your goal is rather to interrupt but then resume the login flow, then this is somewhat accomodated with a predefined set of flow defintions designed to be user-editable in flows/authn/conditions/ The conditions-flows.xml file controls what events are detected and handled, and what to do. The example included responds to a number of events by calling predefined subflows that are themselves just empty examples that return immediately, and then control passes back to the view state that renders the login form. An obvious use for this feature is responding to an imminently expiring password with some kind of warning view; another is detection of a locked account, and the use of a dedicated view to help the user with that condition. In the simplest case, maybe you just want to display a page, in which case you can insert your own In more complex cases, you may need to actually redirect the user out to other functionality implemented outside the IdP, which is something the Spring Web Flow documentation refers to as an external redirect, and it's possible to resume the flow in that scenario as well. If you don't, the user's session is suspeneded and will consume resources until it times out, and that doesn't work well at scale, so you have to be careful with that approach. |
A pluggable implementation of account lockout can be enabled by defining a bean called shibboleth.authn.Password.AccountLockoutManager that implements the AccountLockoutManager interface. A default implementation of this interface is available using a parent bean named shibboleth.StorageBackedAccountLockoutManager (commented out by default in conf/authn/password-authn-config.xml). The default implementation has the following behavior:
Note that each attempt can be separated in time by the specified interval, so a 5 minute interval does not mean all the attempts must occur within 5 minutes, but could occur over a period as long as 5 times the number of attempts. Once an account locks, an "AccountLocked" event is signaled, and the new default configuration maps this event to the "AccountLocked" classified error. If your installation pre-dates this feature, you will likely want to map that event to whichever classified error reporting condition you want to expose to the user. See AccountLockoutManagement for information on the administrative flow that allows management of lockout state. |
With V4, creating a new back-end generally is less work than before and relies on supplying new implementations of the CredentialValidator interface, usually by inheriting from the net.shibboleth.idp.authn.AbstractUsernamePasswordCredentialValidator class. If you built a custom back-end using the older V3 "action bean" contract, that is no longer supported in this version. It's generally straightforward to simplify such a class and turn it into a CredentialValidator. |
A feature included with the Password flow is the ability to present additional login options to the user and call them directly as subflows in response to some form of user input or client-side script. This is useful if you want most users to have the option to use a password, but make more advanced options available at the same time without requiring extra pages or clicks to reach the password option. It is no longer the proper way to implement this requirement, as the warning notes above. Basic SetupSome preconditions for using this feature:
Assuming the above changes are made, to configure this feature you must supply definitions for the following beans in authn/password-authn-config.xml (there are example definitions at the bottom of the file in a comment):
User InterfaceThe above changes trigger the example logic in the login view template (views/login.vm) that iterates over the extended flows, determines which ones are "allowable" for the request, and displays a button to run them. This is obviously a crude UI that you are expected to tailor for your use case, usually by taking advantage of knowledge of the specific methods you're trying to make available and how you want to describe them to users. The UI also includes support for not rendering the Password login form if that method itself isn't allowed. The example buttons will run the corresponding extended flow. If the flow succeeds, the authentication process will complete in the usual manner. If not, the login view will be re-displayed, and the "event" triggered will reflect whatever was returned by the failed flow. In addition, the AuthenticationFlowDescriptor returned by For obvious reasons, it's hard to document exactly how to do all this "correctly" because the UI will be very site-dependent (and quite often will be complex to display). The goal is to supply the template with sufficient information to allow you to script the UI without having to make coding changes.
Additional NotesSome login flows may be implemented to take advantage of the use of this feature in a couple of different ways. A custom login flow can distinguish between being called directly by the IdP and as an extended flow called by another login flow by the presence of a flow variable called "calledAsExtendedFlow". This is automated for the External login flow by making a request attribute available called "extended" when this flow variable is set. It's also possible to pass information across the flow boundary. Any form parameters you include in the form that submits the event to call the extended flow can be captured by adding their names to a bean called shibboleth.authn.Password.ExtendedFlowParameters. Any values for parameters that match a name in that bean will be saved to a map returned by the AuthenticationContext's getAuthenticationStateMap() method. They are not typically preserved on the actual query string that a called flow will see. |
The beans defined in or for use in authn/password-authn-config.xml follow:
|
The beans defined in or for use in authn/password-authn-config.xml follow:
|
The flow-specific properties usable via authn/authn.properties are:
|
The general properties configuring this flow via /authn.properties are:
Most of the flows, including this one, default to describing themselves in terms of "password"-based authentication, so the
In property form, this is expressed as (note especially the trailing commas, which MUST be there):
|
To replace the internally defined flow descriptor bean, the following XML is required:
In older versions and upgraded systems, this list is defined in conf/authn/general-authn.xml. In V4.1+, no default version of the list is provided and it may simply be placed in conf/global.xml if needed. |
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.