The administrative logout feature is a way to address the need to disrupt existing sessions with the IdP in the event of account compromise. The actual implementation of this feature is not based on logout or disrupting sessions, but as “revocation”. This is primarily due to the fact that the default IdP configuration (and most deployments) use client-side storage for sessions, so the IdP cannot actually know what sessions may exist and can’t “delete” them out of band.
A new condition (actually a BiPredicate) attached to login flows (usually globally via some simple properties) determines whether a particular AuthenticationResult is revoked, and if configured to do so the IdP will check this condition before allowing an existing result from a previous login to be reused.
This is effectively the same as the original concept of “reuseConditions” that can be attached to login flows already, but it is implemented separately to make it easier to build custom revocation conditions and to make it easier to support a simple, global enabling/disabling of this feature while still making use of the original feature.
Unlike reuse conditions, which return true to signal that reuse should be possible, revocation conditions are the inverse, returning true to indicate that revocation has happened.
While it is possible (and not simple) to configure this feature on a per-login-flow basis, this is not expected to be a common need so a simpler, global approach is provided based on properties defined in conf/authn/authn.properties (upgraded IdPs can freshen that file by looking at the updated defaults in the dist folder).
The feature is enabled and disabled via the idp.authn.revocation property (defaulting false, it has to be enabled before the rest of the settings are relevant).
When enabled, the idp.authn.revocation.Condition property defines the name of a bean to use as the implementation of the BiPredicate to use. There are two implementations provided with the software:
This implementation relies on a StorageService-backed RevocationCache that can persist revocation records while they’re needed and retrieve them at runtime to apply them. While it can function out of the box using the default in-memory storage back-end, a clustered deployment would obviously require alternatives. It is the default mostly to allow out of the box testing of the feature but is likely not the ideal choice for most deployers unless they already have a well-performing cross-server StorageService.
This implementation abstracts away the back-end storage and management of revocation information and accesses it via a special run of the AttributeResolver, which can be configured easily to “just” resolve a single IdPAttribute to obtain the records. Obviously any DataConnector can be used to obtain them, allowing use of LDAP, JDBC, HTTP, etc. This is more flexible and recommended for production use.
The remaining settings depend in general on which of those options is used.
The actual mechanics of revocation depend on these condition implementations, but the two alternatives supplied both expect the content of a revocation record to be a timestamp (the Unix epoch in seconds, NOT milliseconds). This timestamp signifies the demarcation point such that any login results that were created prior to that time are treated as revoked. This is, in other words, the time at which an account might have been reset and put back under the control of authorized subject(s), i.e., when a password is reset or an account locked.
The cleanup of these records is also dependent on which condition is used. In the case of the RevocationCache approach, the records are provided with a duration for expiration time that obviously needs to be beyond the last necessary use of the value. In the case of the AttributeResolver approach, it is out of scope how cleanup would be done.
To use the AttributeResolver as a source of revocation records, the idp.authn.revocation.attributeId property defines the ID of an IdPAttribute to resolve at runtime to fetch revocation timestamps as discussed above. The ID “revocation” is used by default.
During resolution, the “phase” is set to “authn/revocation”, so it is possible to automatically limit the resolution of this attribute to this use case via the resolutionPhases XML Attribute you can attach to definitions in the resolver. This is a simple way to avoid the need to resolve it during “ordinary” use of the resolver.
The usual fields in the AttributeResolutionContext are populated to allow for scripting, construction of searches, etc. It is entirely arbitrary on what basis the results are compiled but the resulting attribute values must either be of type StringAttributeValue and contain long integers representing the number of seconds since the Unix epoch, as described earlier, or be of type DateTimeAttributeValue. Any login results created prior to any value returned will be considered revoked.
The default condition bean is based on a component of type RevocationCache that we supply and that in turn stores and retrieves records via a pluggable StorageService. Obviously only storage implementations that support the clustering needs of the deployment can be used here. The beans involved are configurable with properties, primarily the idp.authn.revocation.StorageService property identifying which StorageService bean to use.
An administrative REST interface is provided to allow manipulation of the cache (see https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/3032612865). The condition “half” is responsible for fetching records back for enforcement. Storage records have a two part key structure, divided into a context (in this case the string “LoginFlowRevocation” and a key). The key in this case can be of two supported forms:
The first format allows a named principal’s login results to be revoked. The second format allows all attempts to reuse login results originating at a particular address to be revoked. The address variant is an optional feature enabled via the idp.authn.revocation.addressBased property since it doubles the number of read operations performed.
The following properties are defined and commented in conf/authn/authn.properties:
Enables or disables the built-in support for revocation of authentication results (i.e., this whole feature)
Bean ID of a BiPredicate (as shown) that determines whether to revoke the result passed in as the second input parameter. The condition must return true iff the result should be revoked.
This is conceptually the same as the inverse of the “reuseCondition” feature, but is separated to allow the result to be passed in directly for evaluation and to avoid complicating existing use of that feature.
Two implementations are supplied with the software (see Beans below and the documentation above).
When true, errors in obtaining revocation information are treated as fatal and result in revocation. Applies only when the shibboleth.RevocationCacheCondition bean is used (the default).
When true, the shibboleth.RevocationCacheCondition bean will perform both principal- and address-based lookups for revocation records to apply (doubling the number of storage read operations).
Alternate revocation condition settable via idp.authn.revocation.Condition property that resolves an IdPAttribute via the AttributeResolver to obtain revocation records (see documentation above for details)