OPReleaseNotes
- 1 4.2.0 (October 23, 2024)
- 2 4.1.0 (April 11, 2024)
- 3 4.0.0 (September 14, 2023)
- 4 3.4.0 (May 15, 2023)
- 5 3.3.0 (November 29, 2022)
- 6 3.2.1 (July 7, 2022)
- 7 3.2.0 (June 30, 2022)
- 8 3.1.2 (May 17, 2022)
- 9 3.1.1 (April 21, 2022)
- 10 3.1.0 (April 15, 2022)
- 11 3.0.4 (January 31, 2022)
- 12 3.0.3 (January 3, 2022)
- 13 3.0.2 (September 1, 2021)
- 14 3.0.1 (May 25, 2021)
- 15 3.0.0 (March 23, 2021)
4.2.0 (October 23, 2024)
This is a feature release accompanying a new version of the OIDC commons library along with some general improvements and bug fixes. It is compatible with Shibboleth IdP 5.0 or later.
This release addresses security advisory (https://shibboleth.net/community/advisories/secadv_20241023.txt) related to a pair of race conditions in the authorization/authentication request processing.
Getting issues...
Request object handling
In addition to the OIDC-specified request object handling, the plugin now also supports OAuth2 JWT-secured authorization requests (JAR). This logic is applied to the non-OIDC authorization requests to the authorization-endpoint and to all pushed authorization requests (see PAR below).
PAR endpoint
The plugin now supports OAuth2 Pushed Authorization Requests (PAR): a method for clients to push the payload of an OAuth 2.0 authorization request to AS/OP via a direct (API) request. The server provides them with a request URI that is used as a reference to the data in a subsequent call to the authorization endpoint. We provide two methods for the request URI generation: the default method encrypts the state inside the value. The other method exploits a configurable storage service: this way the values remain shorter as the URI value only contains a reference to the storage record.
The full profile documentation is available at OPPushedAuthorization .
DPoP access tokens
In addition to the bearer tokens, the plugin now supports OAuth2 demonstrating proof of possession (DPoP) specification. As described in the RFC: “DPoP can be used to sender-constrain access tokens regardless of the client authentication method employed, but DPoP itself is not used for client authentication. DPoP can also be used to sender-constrain refresh tokens issued to public clients (those without authentication credentials associated with the client_id).”.
The DPoP tokens are now automatically issued to the clients that use valid DPoP proof JWTs in the token request. Several profile configuration options are available for enforcing and customizing the default logic.
Custom request/response message handling
The plugin now offers additional hooks for customizing the request message parsing and the creation of the successful and error response objects. The OPMessageHandling page describes the current features. Similarly to the SAML profiles, the new messageHandler
profile configuration option is now available for OAuth2/OIDC profiles too.
It should be noted that the position of the call to outbound interceptor flows was changed to occur right after the creation of the response message: the logic is now compliant with the one used in the SAML profiles. Previously wired outbound interceptor flows should thus be verified to be interoperable.
New configuration properties
idp.oauth2.par.StorageService: the storage service to be used for storing pushed authorization requests (defaults to in-memory)
idp.oauth2.par.serializationStrategies: a bean containing a map of serialization strategies for the pushed authorization requests (defaults to shibboleth.oidc.DefaultPushedAuthorizationRequestUriSerializationStrategies)
idp.oauth2.par.requestUriType: the pushed authorization request URI value type (default to empty, referring to the method encrypting the state inside the opaque value)
idp.oauth2.par.requestUriLifetime: the pushed authorization request URI lifetime (defaults to 1 minute)
idp.oauth2.dpop.replayCacheLifetime: the replay cache record lifetime if the DPoP proof doesn’t contain expiration time (defaults to 5 minutes)
idp.oauth2.dpop.maxReplayCacheLifetime: upper bound of the DPoP proof lifetime in the replay cache (defaults to 5 minutes)
idp.oauth2.dpop.proofAlgorithms: the algorithms advertised to be compatible for DPoP proofs, defaults to RS256,RS384,RS512,PS256,PS384,PS512,ES256,ES384,ES512
idp.oauth2.par.useOnlyRequestObject: the bean for condition to use only values from request objects within PAR-endpoint (defaults to JAR-logic, i.e. if request object is specified, the values are only fetched from there)
idp.oauth2.authorize.useOnlyRequestObject: the bean for condition to use only values from request objects within authorisation-endpoint
idp.oidc.strictScopeValidation: a flag to use strict scope validation, i.e. a request for unallowed scope leads to an error (defaults to false)
idp.oidc.requestParser.*: request-message specific custom parsers as described in OPMessageHandling.
New configuration beans
shibboleth.oidc.MetadataPolicyRedirectUriValidator: Abstract bean can be used for wiring metadata policy -based custom validators
shibboleth.oauth2.par.AllowedScopeStrategy: Allowed scope lookup strategy for PAR
shibboleth.oidc.par.SignedRequestObjectClaimsValidation: Chain of validators for request object in the PAR endpoint
shibboleth.oidc.DefaultOAuth2ProtectedApiMappedErrors: New error-mapping bean to be used with the OAuth2 protected endpoints, see https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3785326593/OPMessageHandling#Error-handling
4.1.0 (April 11, 2024)
This is a feature release accompanying a new version of the OIDC commons library along with some general improvements and minor bug fixes. It is compatible with Shibboleth IdP 5.0 or later.
Getting issues...
General Note
There is a bug in the Nimbus library we use for much of the functionality in the OP that impacts the way we set and manage cookies within the IdP. This bug manifests in a fairly complex way and was exposed by a fix in V5.1.3 that causes the behaviour to be worse there than before, but there are limitations even on older versions. For versions older than 4.2.0, the following should be taken into account if you run without HTML Local Storage enabled for tracking client sessions:
V5.1.3+
On the latest version, the use of OpenID authorizaton responses that are issued via HTTP Redirect (the most common way) does not allow the IdP’s session cookie(s) to be set at all in affected cases. It is possible to work around this issue to an extent, but we cannot promise that the use of SAML won’t be impacted in certain cases. If you want to attempt this, you need to set idp.cookie.bufferingCondition = shibboleth.Conditions.FALSE
in your properties.
The caveat is that you cannot attach a SameSite attribute to your cookies regardless. That’s simply a consequence of the bug, and there is no workaround.
V5.1.2 and Older
In earlier versions, cookies work in general but SameSite will not be added to the cookies if configured to do so. That issue applied to both SAML and OpenID, and was the reason for the change in V5.1.3 that exposed the Nimbus bug.
OIDC Logout
The OP plugin now includes the new https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3466559581 profile. The new OIDC.Logout profile implements the RP-initiated logout and logout propagation via both front- and back-channel. The profile documentation has a section for slight modifications needed for two logout templates if non-default versions prior to IdP 5.1 are used.
Acknowledgement to DAASI: their OIDC back-channel logout propagation plugin was used as a basis for this implementation.
Refresh token extensions
We have refactored the refresh token encoding and decoding code and it’s now fully customisable. This advanced feature is provided via two new properties idp.oauth2.refreshToken.serializationStrategies and idp.oauth2.refreshToken.deserializers: those can be used for injecting any custom beans to encode and decode refresh token values, and thus provide support for for new refresh token types. We demonstrate this new functionality by supporting a new JWT refresh token type.
Policies for dynamic registration and unregistered clients
The https://shibboleth.atlassian.net/wiki/x/AoC_rw used in dynamic client registration and for unregistered clients can now be extended with custom operators. A new metadata policy operator bean provides flexible means for validating incoming requests via a fully customisable set of beans. See https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/2948497410/OPMetadataPolicies#Custom-operators-4.1 for details.
Metadata-driven claim naming
The RP-specific claim names can now be configured in the metadata-driven fashion. See OPAttributeResolution | SAML metadata driven claim name for more details.
Identifier configuration
The identifier generation configuration has been harmonised: a new configuration property (idp.oidc.xmlSafeIdentifiers
) can be used to control whether to generate XML ID safe identifiers, which was previously always the case. If the property is set to false (default is true), the identifiers (such as JWT token IDs) won’t contain the _
-prefix anymore and the OP can, for instance, create UUIDv4 compatible identifiers if desired.
Message logging improvements
The request and response messages containing JSON structures are now pretty-printed on TRACE level. Also the JWT token payloads produced by the OP plugin are pretty-printed to the protocol message logs on that level.
New configuration properties
idp.oauth2.refreshToken.type: a format of refresh token. Supported values are “JWT” or nothing/empty/null, implying opaque tokens.
idp.oauth2.refreshToken.serializationStrategies: a custom bean reference containing the map of refresh token serialisation strategies, key refers to the refresh token type.
idp.oauth2.refreshToken.deserializers: a custom bean reference containing the list of refresh token deserialisers.
idp.oauth2.responseModes: a comma-separated list of allowed response modes. Empty by default which refers to no restrictions.
idp.oidc.xmlSafeIdentifiers: a flag to signal if XML ID safe identifiers should be used when generating identifiers.
idp.oidc.logout.encryptionOptional: a flag to automatically disable back-channel logout token encryption if the relying party does not possess a suitable key.
idp.oidc.logout.preferFrontChannel: a flag to prefer front-channel logout propagation if both front and back -channel URIs are defined in the RP metadata
idp.oidc.logout.frontChannelSuccess: a flag to consider front-channel logout propagation success in the propagation UI (defaults to false).
idp.oidc.logout.revokeTokens: a flag to revoke the access and refresh tokens related to the session (defaults to true). Note that the OAUTH2.Revocation profile must be enabled for the RP.
idp.oidc.logout.requireIdTokenHint: a flag to require the use of id_token_hint parameter in the RP-initiated logout request.
idp.oidc.logout.logoutHintMatchingStrategy: a custom bean reference to bi-predicate for matching the logout_hint parameter with an SPSession.
New configuration beans
shibboleth.oidc.RevokeConsentPredicate: A predicate to signal if prior consent should be revoked.
shibboleth.oidc.UnregisteredClientPolicyValidator: A validator bean used for validating the configured policy for unregistered clients.
shibboleth.oidc.UnregisteredClientPolicyEnforcer: An enforcer bean used for enforcing policy for unregistered clients.
shibboleth.oidc.dynreg.ClientIDGenerationStrategy: An identifier generation strategy used for generating client IDs in dynamic client registration.
shibboleth.oidc.dynreg.ClientSecretGenerationStrategy: An identifier generation strategy used for generating client secrets in dynamic client registration.
shibboleth.oidc.dynreg.MetadataPolicyValidator: A validator bean used for validating the configured metadata policy in dynamic client registration.
shibboleth.oidc.dynreg.MetadataPolicyEnforcer: An enforcer bean used for enforcing metadata policy in dynamic client registration.
4.0.0 (September 14, 2023)
This is a feature release accompanying a new version of the OIDC commons library along with some general improvements and minor bug fixes. It is the first release that requires Shibboleth IdP 5.0.0 or later. Previous versions of the plugin are not compatible with IdP 5.
Getting issues...
Policies for unregistered clients
In addition to the request validation against client metadata (JSON or SAML), the plugin now supports validation against a policy for unregistered clients. A policy is used for validating the incoming client ID, scope, redirection URI, and response type parameters or their subsets, depending on the endpoint where the validation is done. If the request is compliant with the policy, the unverified profile configuration is applied. The validation against policy is only performed with the unverified profile configurations (see shibboleth.UnverifiedRelyingParty in https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508044 ). The verified profile configurations (shibboleth.DefaultRelyingParty and shibboleth.RelyingPartyOverrides) still require the registered client metadata in the same way as before.
Elimination of the custom response header filter
The previously existing method for configuring custom HTTP headers for the plugin’s endpoint has now been removed. Now the plugin automatically extends the IdP’s known set of URL prefixes to apply its response headers to by adding the /profile/oidc/
and /profile/oauth2/
prefixes to the built-in set.
See OPCustomFilterRegistration .
New configuration properties
idp.oidc.DefaultUnregisteredPolicyFile - it defaults to %{idp.home}/conf/oidc-unregistered-client-policy.json. An example file is included in the distribution.
Removed configuration properties
idp.oidc.ResponseHeaderFilter: It was related to the now removed custom response header filter
idp.oidc.refreshToken.defaultLifetime: already deprecated in version 3.3.0, use idp.oidc.refreshToken.defaultTimeout instead
New configuration beans
shibboleth.oidc.Conditions.MetadataValueEquals: a utility bean to be used for instance with activation conditions to match if a specific metadata claim contains a specific value
shibboleth.oidc.PlainRequestObjectClaimsValidation: If defined, it will be used for the validation of unsigned request objects
shibboleth.oidc.SignedRequestObjectClaimsValidation: If defined, it will be used for the validation of signed request objects
3.4.0 (May 15, 2023)
Getting issues...
This is a feature release accompanying new version of the OIDC commons library along with some general improvements and minor bug fixes. It is the first release designed to co-exist with the new OIDC RP authentication plugin.
This release addresses security advisory (https://shibboleth.net/community/advisories/secadv_20230512.txt) related to a pair of race conditions in the client authentication and dynamic registration features.
This release requires Shibboleth IdP 4.3.0 or later and the OIDCConfig plugin. Please note that the version 1.0.1 was released on May 16, 2023 to fix issues (see first and second) related to default OIDC.SSO and OAUTH2.Token configurations.
Security Configuration
The old security configuration mechanism has been replaced with the new security configuration style, designed to be compatible with the new OIDC RP authentication plugin. Any custom security configuration dating to previous versions will require modifications, but this is expected to have been rare.
The underlying Java class for the shibboleth.oidc.DefaultSecurityConfiguration parent bean has changed, and thus any custom beans extending that need to be adapted. The previous class is no longer compatible with the plugin.
The new class bean has the following properties:
jwtSignatureSigningConfiguration (related property idp.oidc.signing.config, NOTE, any previously configured bean needs to be adapted)
jwtEncryptionConfiguration (related property idp.oidc.encryption.config, NOTE, any previously configured bean needs to be adapted)
jwtDecryptionConfiguration (related new property idp.oidc.decryption.config)
jwtSignatureValidationConfiguration (related new property idp.oidc.validation.config)
The following configuration parameters (and related properties) are no longer supported:
requestObjectDecryptionConfiguration (property idp.oidc.rodecrypt.config is ignored)
use jwtDecryptionConfiguration with OPAuthorization
requestObjectSignatureValidationConfiguration (property idp.oidc.rovalid.config is ignored)
use jwtSignatureValidationConfiguration with OPAuthorization
tokenEndpointJwtSignatureValidationConfiguration (property idp.oidc.tevalid.config is ignored)
use jwtSignatureValidationConfiguration with OPToken , OPRevocation and https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/1376879310
New Supported Algorithms
The set of supported algorithms has been extended to include:
PS256, PS384 and PS512 signature algorithms
RSA-OAEP-384 and RSA-OAEP-512 encryption algorithms
ECDH-ES+A128KW, ECDH-ES+A192KW and ECDH-ES+A256KW encryption algorithms
Refresh Tokens
The OPToken profile now contains new profile configuration options to control the expiration of both single and chains of refresh tokens. We also deprecated the previously existing option and property related to the expiration of a single token.
NOTE: The default lifetime for the chain (refreshTokenChainLifetime -option and idp.oidc.refreshToken.defaultChainLifetime -property) is 2 hours. This new option may need to be adjusted to keep any longer-lived refresh tokens valid.
Refresh tokens can now be issued for OAuth2 (non-OIDC) clients via the authorization code grant, if the necessary profile configuration option is set. The OIDC clients still need to use offline_access scope, as before.
A new profile configuration option (issueIdTokenViaRefreshToken) now exists for controlling ID token issuance when the refresh token grant is used and defaults to true.
Request Objects
The OPAuthorization profile now contains new profile configuration options to control the use of request objects.
JWT-based Client Authentication Improvement
The audience validation for JWTs used in client authentication has been modified. The token, introspection and revocation endpoints now accept the OP issuer value, the requested endpoint URL and the token endpoint URL values as an audience. In the older versions, only the requested endpoint URL was accepted.
The validation key handling has also been improved: if the header of an incoming JWT contains a key reference (the kid claim), it must now match to a trusted key.
3.3.0 (November 29, 2022)
Getting issues...
This is a feature release that adds support for OAuth2 (non-OIDC) authorization requests along with some general improvements and minor bug fixes.
The OIDC.SSO profile can now be configured to also accept plain OAuth2 authorization requests. Before this release, the RPs were required to use OIDC authentication requests. It remains the default behaviour, but it can be configured via idp.oauth2.requireAuthenticationRequestPredicate
property.
3.2.1 (July 7, 2022)
Getting issues...
This is a patch release, primarily addressing a bug related to the use of revocation endpoint with JWT access tokens. The patch is very important for deployments that have enabled the use of JWT access tokens with revocation and have the revocation method set to “TOKEN” (another new feature introduced in V3.2.0).
3.2.0 (June 30, 2022)
Getting issues...
This is a feature release that adds some new capabilities along with a bug fix regarding the use of SAML metadata for OIDC RPs.
JWT Access Tokens
As with the client_credentials grant since version 3.1, all access tokens can now be configured to use the JWT format. Both authorization and token endpoints now support the “resource” parameter extension from RFC8707 in order to influence a JWT access token’s audience.
Note that when combining the use of this feature with standard OIDC, access token encryption under a resource server’s key is generally impossible since the OP must be able to consume the token when presented by the RP. This has privacy implications when including custom claims about the subject in the token.
Token Revocation Enhancements
The revocation endpoint can now be configured to either revoke a single token at a time or the entite chain of tokens issued via a given code grant. Previously, it always revoked the full chain, which remains the default setting. In addition to the revocation method, the full chain revocation lifetime can now be configured on the revocation profile configuration.
The token profile configuration also now contains a flag fo enforce refresh token rotation; when enabled, the refresh token used for requesting new access and refresh tokens is revoked after a single use. If an already revoked refresh token is used, the full chain corresponding to that token is revoked. This aligns the behavior to suggested practice published in Internet Drafts.
Authorizing Requested Scopes
The set of allowed scope values an RP can request can now be fully customised, for instance depending on the authenticated subject's attributes. See https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3001352203 for more information and examples.
Protocol Message Logging
OIDC/OAuth request and response messages are now logged via the PROTOCOL_MESSAGE.OAUTH2 category (a sub-category of the one used for SAML, which we will likely migrate to a subcategory in a future IdP release). At DEBUG level, it logs the contents of the Java message objects, without revealing the value of client secrets or HTTP Basic-Auth headers. At TRACE level, it logs the messages in raw form, including both HTTP headers and message body contents. The TRACE level matches the logging that was previously done by the decoder/encoder class loggers on DEBUG level.
ID Token and Token-encoded Claims Set Manipulation
The profile configurations now contain hooks for manipulating (i.e. modifying, adding or removing) claims in ID Tokens and in the claims sets that are encoded inside opaque authorization codes and access/refresh tokens. This is an advanced feature that is meant to be used with extra care: the deployer is responsible for keeping the claims sets syntactically correct and not violating specifications.
3.1.2 (May 17, 2022)
This is a patch release, addressing issues related to OIDC claim requests and JWT client authentication to introspection and revocation endpoints.
3.1.1 (April 21, 2022)
This is a patch release, primarily addressing https://shibboleth.atlassian.net/browse/JOIDC-91 , which prevented public clients from accessing token endpoint.
3.1.0 (April 15, 2022)
This is a significant feature release that adds a number of new capabilities along with various fixes. It is meant to be compatible with the V3.0 releases at a feature/configuration level, but there are few changes that may impact a very small number of deployers.
API Changes and Future Policy
Because of the relative immaturity of the code base, some classes are still moving around. Because we do not expect that most deployers should have a need to directly interact with these classes at a Java level, we have made some changes that contradict our usual API versioning policy; in particular the profile configuration classes were migrated out of an OP package and into the OIDCCommons library for reuse, and some advanced “context” classes used to store information during the handling of requests have been moved as well.
As a general statement to prevent confusion in the future, please treat anything in the OP itself as an implementation class, despite the presence of a separate API module. That is, any classes in packages under “net.shibboleth.idp.plugin.oidc.op” should be viewed as subject to change and not formally in the API, though we try and limit the changes in the idp-oidc-extension-api module.
Classes in the OIDCCommons API modules (the ones ending in -api) that are packaged under “net.shibboleth.oidc” will be maintained in accordance with our versioning policy, so when classes appear there, they should be in more stable form.
Client Registration Enhancements
A number of major enhancements have been made to https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/1376879077:
Access tokens for use in controlling client registration, which can be issued via OP operations staff or directly to client application owners subject to policy.
Metadata policy statements that can limit what gets registered, including on a per-access token basis.
An endpoint to query and delete registrations.
Client Authentication Enhancements
OAuth/OIDC client authentication has been redesigned in this release to support the IdP’s login flow machinery, and a new (default) login flow called OAuth2Client has been created, modeled on the Password login flow built-in to the IdP. Because it is a separate flow and relies on separate configuration properties and beans, it supports operation in parallel with the standard Password flow while sharing much of its capabilities, as well as allowing for features that are applicable only to OAuth clients, such as client secret validation and use of signed JWT objects.
See https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/2930409507 for more information.
Client Credentials Grant
The Token endpoint has been enhanced to support additional, OAuth-specific use cases, starting with the “client_credentials” grant type that supports direct requests for access tokens by OAuth clients rather than via a browser. Support for this grant type includes the new option to issue access tokens in JWT format (including optional encryption) as well as the original opaque format.
As part of this new work, the configuration for the Token profile has been split off from the original OIDC.SSO profile bean and a second profile configuration added for TokenAudience to control the behavior of the system when issuing tokens intended for use with particular resource servers. For compatibility, the system will operate in the same fashion as before by default, supporting only the authorization_code and refresh_token grants in an OIDC-specific fashion. The new beans can be added to the RelyingPartyConfiguration as desired to enable and control the new features.
See https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/2930606124 for more information.
Please note that presently, the only “pure” OAuth use case supported is the “client_credentials” grant. Support for OAuth-only use of the code grant and JWT access tokens for “4 legged OAuth” use cases is a future development task.
Unverified Use of OAuth Features
The aforementioned “client_credentials” grant and the token introspection and revocation features have been enhanced and tested for use with authenticated clients lacking explicit client metadata, allowing enablement (if desired) via the “UnverifiedRelyingParty” configuration. Support for the OIDC profile does not yet support this, but should in the future.
Custom Filter Registration
A configurable Servlet Filter can now be registered without a need to edit the web.xml file. This is useful to support custom HTTP request or response handling. See OPCustomFilterRegistration for more information. Related to this topic, also see https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/2958163969 for information about a new IdP 4.2 feature.
3.0.4 (January 31, 2022)
This is a patch release addressing security advisory related to (https://shibboleth.net/community/advisories/secadv_20220131.txt) unchecked use of the request_uri
feature.
If you are supporting RPs that issue requests by reference to a hosted JWT object, you will need to add the exact URLs to those objects into the client’s metadata to validate the locations. This upgrade will block unregistered values. Note that we did not support dynamic client registration of those URLs and have no plans to do so given the complexity of validating them, but we may add a hook for supporting this if there is demand to do so in the future.
3.0.3 (January 3, 2022)
This is a patch release, primarily addressing security advisory (https://shibboleth.net/community/advisories/secadv_20220103.txt) related to incomplete incoming JWT validation.
If you are relying on JWT client authentication, this fix may result in failure to validate any non-compliant tokens that do not contain the proper claims and meet other security requirements defined by the specifications.
3.0.2 (September 1, 2021)
This is a patch release, primarily addressing https://shibboleth.atlassian.net/browse/JOIDC-52 , which prevented the use of authorization codes and access/refresh tokens produced by the earlier versions of the extension. Some incompatibilities still remain, they’re highlighted in https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/2769420329 .
3.0.1 (May 25, 2021)
This is a patch release addressing some bugs and updating some of the exploited 3rd party libraries.
This version is a certified OpenID Provider.
3.0.0 (March 23, 2021)
This is the first version which is compatible with the concept of plugins introduced by Shibboleth IdP V4.1. The older versions of the OIDC extensions are no longer supported.
For installation / upgrading, see https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/1376878984