Release notes · 8.1.0 development
8.1.0-RC2
The second release candidate hardens OAuth, OpenID Connect, SAML2 and the CAS protocol across many flows, moves verifiable credentials to the final OpenID4VCI 1.0 format, and fixes how consent decisions are stored and revoked.
- Requires JDK 25
- Runs on Java 27
- Built with Gradle 9.8
- 556 browser test scenarios
- 21New & noteworthy topics
- 6Changes to review before upgrading
- 5Other changes
- 7Fixes
Before You Upgrade
These changes alter existing behavior. Each one links to its full description below.
-
Action
Verifiable credential wallets must speak the final OpenID4VCI 1.0 wire format; draft 13 requests are no longer understood.OAuth & OpenID Connect
-
Changed
Client secrets are now compared case-sensitively.OAuth & OpenID Connect
-
Action
Groovy consent activation scripts must return a
ConsentQueryResultinstead of a boolean.Attributes & Consent -
Changed
CAS validation responses report
INVALID_TICKET_SPECandINTERNAL_ERRORwhere they used other codes, and replace characters that are not legal in XML attribute names with_.CAS & Other Protocols -
Changed
SAML2 metadata fails to load when its signature certificate cannot be read, and HTTP downloads are capped at 256 MiB by default.SAML2
-
Changed
Theme names without a matching theme definition are ignored, and the next resolver or the default theme applies.Interface & Accounts
Spotlight · Palantir admin dashboard
Restore an Earlier Version of a Service
- The service history endpoint restores a selected revision to the registry and the live cache, keeping its history.
- Palantir offers a Restore Version action under View Change History.
- The OpenID Connect service wizard gains a verifiable credentials policy section.
Highlights
-
OAuth & OpenID ConnectChanged
OAuth & OpenID Connect Hardening
Replay protection across nodes, client-bound token exchange, introspection and DPoP, and spendable DPoP-bound tokens.
-
SAML2Changed
SAML2 Identity Provider
Independently validated request signatures, atomic metadata resolution, MDQ fixes and pooled HTTP clients.
-
OAuth & OpenID ConnectAction
OpenID Connect Verifiable Credentials
The finalized OpenID4VCI 1.0 wire format, per-service credential types and configurable credential lifetimes.
-
CAS & Other ProtocolsFixed
CAS Protocol
Responses can no longer be forged through line breaks or markup, and
renewis evaluated per request. -
Attributes & ConsentFixed
Attribute Consent
Every consent decision gets its own identifier, and lookups and revocations work across all stores.
-
Platform & OperationsNew
JMX Management
Service reloads, ticket and session counts, cleanup and diagnostics are now available over JMX.
New & Noteworthy
The following items are new improvements and enhancements presented in this release.
OpenRewrite Recipes
CAS continues to produce and publish OpenRewrite recipes that allow the project to upgrade installations in place from one version to the next. See this guide to learn more.
Graal VM Native Images
A CAS server installation and deployment process can be tuned to build and run as a Graal VM native image. We continue to polish native runtime hints. The collection of end-to-end browser tests based on Puppeteer have selectively switched to build and verify Graal VM native images and we plan to extend the coverage to all such scenarios in the coming releases.
Testing Strategy
The collection of end-to-end browser tests based on Puppeteer continue to grow to cover more use cases
and scenarios. At the moment, total number of jobs stands at approximately 556 distinct scenarios. The overall
test coverage of the CAS codebase is approximately 94%.
Java 27
CAS may be built and run using Java 27 and the build process has been updated to use
the latest Java 27 features and capabilities. Please note that this is only a preparatory step for future
releases and the baseline requirement will remain as it was.
Gradle 9.8
CAS is now built with Gradle 9.8 and the build process has been updated to use the
latest Gradle features and capabilities.
Spring Boot 4.2
CAS is now built on top of Spring Boot 4.2.x. This is an in-progress ongoing minor platform upgrade that
affects almost all aspects of the codebase including many of the third-party core libraries used by CAS
as well as some CAS functionality.
Please refer to the Spring Boot Wiki for more information on the changes and updates in this release. The biggest change to CAS would be support for AMQP 1.0.
REST password management, trusted-device storage, Clickatell SMS and Spring Boot Admin registration now use Spring’s
RestClient in place of deprecated RestTemplate APIs.
JSpecify & NullAway
CAS codebase is now annotated with JSpecify annotations to indicate nullness contracts on method parameters, return types and fields. We will gradually extend the coverage of such annotations across the entire codebase in future releases and will integrate the Gradle build tool with tools such as NullAway to prevent nullness contract violations during compile time.
OpenID Connect Verifiable Credentials
Several improvements are now available for OpenID Connect with Verifiable Credentials:
- CAS may require specific principal attributes to determine eligibility before a credential offer transaction can be created for a principal.
- Pre-authorization codes are now also properly updated and removed from the ticket registry after a credential offer transaction is completed once the ticket is expired.
- Access tokens used for credential issuance are now bound to the credential configuration id when the token is minted; this is then enforced when the token is used to request credentials.
- Transaction-code requirements are enforced during token exchange.
- A pre-authorized code is now redeemed atomically, before the access token is minted, rather than being marked used afterwards. Previously two concurrent exchanges of the same code could each receive an access token, since the code was only updated once the token already existed. OpenID4VCI requires the code to be single use.
- Credential batch issuance is limited and capped at a predefined limit.
- OpenID Connect discovery now advertises
noneamongtoken_endpoint_auth_methods_supported, andnoneis understood as a client authentication method. CAS already accepted unauthenticated token requests for grants that carry their own proof of authorization, such as the OpenID4VCI pre-authorized code, but never said so; a client with no credentials had no way to discover that and would choose a method it could not satisfy. - OpenID Connect discovery now publishes
token_endpoint_auth_signing_alg_values_supported. RFC 8414 requires this wheneverprivate_key_jwtorclient_secret_jwtappears intoken_endpoint_auth_methods_supported, which CAS advertises by default, and clients that enforce the requirement previously refused to use the authorization server at all. The published list is configurable and, as the specification requires, excludesnone. - Credential issuance now speaks the finalized OpenID4VCI 1.0 wire format rather than draft 13. The credential request takes
proofs(plural) and acceptscredential_identifier; the credential response is acredentialsarray and no longer carriesformat. The separate batch credential endpoint is removed, since a batch is now one request carrying several proofs, and the issuer metadata advertisesbatch_credential_issuanceinstead ofbatch_credential_endpoint. The proof challenge is no longer returned from the token endpoint, and the nonce endpoint returnsc_noncealone. - The outcome of a verifiable presentation now reaches the relying party that asked for it. Previously the wallet was told whether its presentation verified and the transaction was deleted, leaving the relying party with no way to learn the result or the disclosed claims. A new
oidcVcPresentationResultendpoint, protected by the same client authentication as the request creation endpoint, reportspendinguntil the wallet answers and then delivers the outcome together with the disclosed claims, once. - Verifiable presentation requests are now delivered the way OpenID4VP requires. A request made under the
redirect_uriclient identifier prefix cannot be signed, and a request URI must serve a signed request object, so CAS now carries the whole authorization request by value in the wallet deep link and no longer offers a request URI in that mode. Settingcas.authn.oidc.vc.presentation.client-identifier-prefixtoX509_SAN_DNSsigns the request object and serves it by reference asapplication/oauth-authz-req+jwt. Previously CAS advertised a request URI that returned a plain JSON document. - The credential endpoint now behaves as an OAuth protected resource. A missing, unknown or expired access token is answered with
401and aWWW-Authenticatechallenge in the scheme the wallet used, rather than400 invalid_request. Other failures now carry the credential error codes OpenID4VCI defines, such asinvalid_credential_request,unsupported_credential_type,credential_request_denied,invalid_proofandinvalid_nonce, instead of a single opaqueinvalid_request. The split betweeninvalid_proofandinvalid_nonceis what lets a wallet tell a stale nonce, which it can recover from by fetching a new one, from a proof it cannot fix. - The authorization-code flow for verifiable credentials no longer ignores confidential clients or requests without PKCE. The response builder previously claimed the request only when the client had no secret and sent a code challenge; every other client had its
authorization_detailsquietly dropped, and the failure surfaced much later as a refusal at the credential endpoint. OpenID4VCI 1.0 only recommends PKCE and places no restriction on confidential clients. A credential the client cannot be granted is now reported asinvalid_authorization_detailsper RFC 9396 rather than dropped. - Credential types are now authorized per service. Previously the offer endpoint and the authorization-details filter only checked that a credential configuration id existed in
cas.authn.oidc.vc.issuer.credential-configurations, so any registered client could obtain any credential the deployment defined. An OpenID Connect service can now carry averifiableCredentialsPolicynaming the credential configuration ids it may obtain, enforced when an offer transaction is created, when authorization details become an authorization code, and again at the credential endpoint when the token is spent. A service with no policy, or a policy that names no credential types, may obtain everything the issuer publishes, so existing deployments are unaffected. - A service’s verifiable credentials policy may also narrow the algorithms its credentials are signed with, through
credentialSigningAlgValuesSupported. Like the credential types on the same policy it can only narrow: the effective set is the intersection with what the credential configuration advertises. - Verifiable credentials are no longer signed as if they were ID tokens. A credential was passed to the ID token signing service, so a client with
encryptIdTokenreceived a JWE rather than an SD-JWT,signIdToken=falseproduced an unsigned credential, and the algorithm came from the client’sidTokenSigningAlginstead of the advertisedcredential-signing-alg-values-supportedwhich CAS’s own verifier then rejected. Credentials are now always signed, never encrypted, and use the first advertised algorithm the issuer key can perform, with the advertised list enforced as the permitted set. - Issued credentials now honor a configurable lifetime per credential configuration,
cas.authn.oidc.vc.issuer.credential-configurations[].credential-validity, which defaults to thirty days. Previously every credential expired five minutes after issuance, which left it unusable by the time a wallet had stored it.
OAuth and OpenID Connect
OAuth and OpenID Connect security have been strengthened across several flows.
- Client assertions now require matching subject, issuer, and client identifiers.
- JWT IDs are tracked through the shared ticket registry to prevent replay across clustered deployments.
- Device and CIBA polling are bound to the authenticated client and completed poll-mode requests are consumed.
- Dynamic client key registrations are memory-bounded.
- Token exchanges are now authorized against the authenticated requesting client, and exchanged tokens cannot gain scopes beyond those granted to the subject token and allowed for the requesting client.
- Client secrets are now compared and enforced using a case sensitive strategy.
- Token introspection reports tokens from other clients as inactive, while revocation only affects the requesting client’s tokens and no longer reveals whether other tokens exist.
- DPoP-bound access tokens can now be spent. CAS answers the token request with
token_type: DPoPwhenever a proof accompanies it, but protected resources recognized theBearerauthorization scheme alone, so a client following RFC 9449 section 7.1 and presenting the token asAuthorization: DPoP ...was told the token was missing. The userinfo, JWKS registration and credential endpoints now accept either scheme. - DPoP proofs are now verified at protected resources through a single
validateProtectedResourceRequestoperation on the proof-of-possession validator. The credential endpoint previously accepted a DPoP-bound access token on presentation alone, which left the sender constraint doing nothing; it now answers a missing or invalid proof with401andWWW-Authenticate: DPoP error="invalid_dpop_proof". The userinfo endpoint keeps the same checks but no longer runs the token endpoint’s verifier over a resource request in addition to the correct one, and the resource-side check now includes the single-usejticheck. - DPoP proof validation no longer takes the client identifier from the unauthenticated
client_idrequest parameter. The identifier is resolved from the authenticated profile first, then from the access token, and only then from the request, which matters for grants that carry their own proof of authorization rather than client credentials, such as the OpenID4VCI pre-authorized code. Validation also no longer overwrites the profile identifier when that identifier belongs to the subject rather than the client. - Single-use checking for DPOP proofs is now enforced using the CAS ticket registry. Furthermore, DPOP requests are no longer treated as a form of client authentication and now sit on top of existing client authentication approaches such as client ID and client secret for confidential clients or PKCE.
- User-Managed Access resources and policies are now bound to both the authenticated client and resource owner. New resource registrations also receive non-sequential, server-assigned identifiers.
WebAuthn Multifactor Authentication
FIDO2 WebAuthn multifactor authentication receives the following improvements:
- Authentication and QR session proofs are now principal-bound and single-use, and configured user verification is enforced for assertions.
- Credential and user-handle resolution now avoids repeated repository-wide scans.
Duo Multifactor Authentication
Duo Security multifactor authentication receives the following improvements:
- REST passcodes now require completed primary authentication, and Universal Prompt callbacks validate browser-session state before restoring the flow.
- Duo Auth and Admin API clients now reuse outbound connection pools across requests.
SAML2 Identity Provider
SAML2 identity provider support receives the following improvements:
- Presented SAML2 authentication request signatures are now validated independently of the metadata signing requirement. Only a successfully validated signature may authorize an assertion consumer service URL that is not registered in service provider metadata.
- IdP-initiated SSO now also requires a caller-provided
shireto match a POST assertion consumer service registered in metadata. - Inbound encrypted SAML2 identifiers now use CAS’s matching IdP encryption certificate and private key for decryption.
- Signature algorithm inclusion and exclusion policies are now enforced consistently across all inbound SAML bindings.
- The
Addressfield of the SAML2SubjectConfirmationDatais now populated with the requester’s IP address when possible. - SAML2 metadata cache entries are now isolated by registered service and resolved without scanning unrelated cached resolvers.
- SAML2 authentication request session entries are updated per session and consumed after callback correlation, avoiding controller-wide serialization and retained replicated-session state.
- Storage-backed SAML2 metadata resolution now uses the requested entity ID to limit document lookups and resolver rebuilds.
- SAML2 SOAP attribute queries and artifact resolutions now require independently validated signatures, message freshness, destinations, and replay protection; artifact tickets are relying-party bound and consumed atomically.
- SAML2 single logout now validates request freshness and replay, fully authenticates and correlates logout responses, and generates actuator logout requests with the correct IdP issuer and service-provider destination.
- Identity provider metadata is now resolved atomically, so concurrent requests can no longer observe a metadata document, or the signing and encryption credentials that belong to it, that was installed on behalf of a different registered service.
- A service provider metadata backup file is no longer deleted ahead of a download attempt, and is used as a fallback when the remote metadata source or MDQ server cannot be reached, so a momentary outage there no longer takes the service offline.
- A service that defines a metadata signature location now fails to load its metadata when that certificate cannot be read, rather than loading the metadata unverified.
- Downloaded service provider metadata is written to its backup file in a single step, so services that share one metadata location can no longer read a partially written document.
- The JDBC and MongoDB identity provider metadata stores now scope the global document lookup to the global owner, so a service’s own document and keys can no longer answer in its place.
- Metadata query requests now ask for
application/samlmetadata+xmlvia theAcceptheader, as the SAML profile for the Metadata Query Protocol requires, and are issued through the CAS HTTP client so they use the deployment’s TLS trust store and hostname verifier. - The SAML2 metadata health indicator answers from the local metadata backup copy where one exists, instead of reaching out to every service’s metadata host on every health check.
- SAML2 metadata user interface information is resolved once per login attempt rather than twice, and dynamically-resolved entities are cached, so rendering the login page no longer issues a metadata query per request.
- Outbound HTTP calls now reuse their underlying HTTP client and its connection pool instead of building and discarding one per request, which recovers connection reuse and stops the server accumulating open sockets over time.
- Service names can no longer resolve per-service identity provider metadata directories outside the configured metadata root. Explicit
idpMetadataLocationsettings remain supported. - HTTP response buffering now limits downloads, including decompressed bodies, to 256 MiB by default. The limit can be changed with the
org.apereo.cas.util.http.HttpRequestUtils.maximumResponseSizesystem property or overridden per request.
CAS Protocol
- The CAS
1.0validation response is line-delimited and carries no escaping mechanism. Principal identifiers and rendered attribute lines are now stripped of line breaks, so a value that contains a newline can no longer forge additional lines in the response. - A proxy-granting ticket is now issued only after the service ticket, the validation specification and the
authentication context have all been accepted. The
pgtUrlcallback used to be contacted and the proxy-granting ticket minted before any of those checks ran, so presenting a leaked service ticket could drive an outbound request and leave an unused proxy-granting ticket behind even though validation went on to fail. - Validation responses now use the protocol’s own error codes for two cases that previously reported something else.
A ticket that fails the validation specification without a
renewrequest is reported asINVALID_TICKET_SPECrather thanINVALID_TICKET, and an unexpected failure during validation is reported asINTERNAL_ERRORrather thanINVALID_REQUEST, which stays reserved for a request that is missing required parameters. A ticket that did not come from an initial login whilerenewwas requested continues to be reported asINVALID_TICKET, as the protocol specifies. - Attribute names are now sanitized into valid XML names before they are rendered as elements in the CAS
2.0/3.0validation response, and proxy URLs in<cas:proxy>are XML-escaped. Previously an attribute name was only stripped of spaces and a proxy URL was written out verbatim, so either could carry markup or quoting characters into the response. Note that a name containing characters that are not legal in an XML name — a colon, for instance — now renders with those characters replaced by an underscore; such a name previously produced a response that was not well-formed XML. - The SAML
1.1validation response now setsRecipientto the service URL the response is intended for, and reservesInResponseTofor theRequestIDof the request being answered, omitting it when the caller did not send one.InResponseTopreviously carried the hostname of theTARGETservice unless aRequestIDhappened to be present, andRecipientwas never set at all, so a relying party had no way to bind the response to its own request or endpoint. - The
renewparameter presented to the CAS protocol validation endpoints is now evaluated per request. Validation specifications are shared components and the requested value used to be assigned onto them for the duration of a request, which allowed a concurrent validation request to reset it. A service ticket that was not issued from a new login can no longer satisfy arenew=truevalidation because of another request that happened to be in flight at the same time.
Views and Themes
- The REST-based view resolver no longer forwards credential-bearing request
headers, such as
Cookie,AuthorizationandProxy-Authorization, to the external template endpoint. - Every resolved theme name is now matched against a real
theme definition before it is honored, no matter how the
name was chosen. A name without a matching
[theme].propertiesfile, either at the root of a configured template prefix or at the root of the classpath, is ignored and the next resolver in the chain applies. This closes a gap where names taken from a request header, cookie or session value were used without any check, and it makes the Groovy and REST theme sources hold to the same contract as every other theme: a script or endpoint that returns a name with no theme definition behind it now falls back to the default theme rather than selecting a theme that does not exist. - A service theme is now resolved once per request rather than once per template lookup, so service resolution, access strategy evaluation and theme file lookups no longer repeat for every fragment rendered on a page.
- Thymeleaf template caching now takes effect. The chaining template resolver previously declared every resolution
non-cacheable regardless of
spring.thymeleaf.cache, so each page and each fragment was re-resolved and re-parsed on every request. Resolutions are now cached per the configured setting, except for those produced by a theme-aware resolver: those map one template name to different files depending on the request’s theme, and Thymeleaf’s cache key does not carry the theme, so they remain non-cacheable. Deployments with no themed template overrides cache every template; deployments with themed overrides cache everything except the overridden templates.
LDAP Integrations
- Surrogate authentication, delegated authentication profile selection, acceptable usage policy and password management now build their LDAP connection pools once and reuse them across requests.
- LDAP connection pools are now addressed by the directory and base DN they serve, so multiple configuration blocks that point at the same server no longer collapse onto a single set of connection settings.
- Surrogate search filters that do not reference the impersonated account are now rejected, as such a filter is unable to restrict the accounts a user may impersonate.
MongoDB Integrations
- A configuration refresh no longer drops MongoDB collections.
drop-collectionanddrop-indexesdescribe what happens at startup, but a refresh of the MongoDB ticket registry or service registry re-ran them and destroyed live tickets or registered services. Collection and index creation still runs on refresh, as it is repeatable. - The MongoDB ticket registry no longer reports a storage failure as a missing ticket. Adding, updating or fetching a ticket now surfaces the underlying failure instead of logging it and carrying on, so a database outage, an oversized document or a ticket definition missing from the catalog can no longer look like a successful login followed by an invalid ticket.
- Result limits are now applied by MongoDB rather than after the fact, so paging through tickets and querying the ticket registry no longer fetch and deserialize whole collections only to discard them. Cursors opened across several collections are now closed even when the caller stops reading early, and collections shared by more than one ticket definition are read and counted once.
- An
IDX_PRINCIPALindex is now created on every ticket collection. Queries by principal, such as removing all tickets issued to a user, run against all collections while only the ticket-granting ticket collection carried the index. - Querying single sign-on sessions by an attribute whose name contains a dot now matches. Such names are escaped when the document is written, and the query did not apply the same escaping.
JMX Management
JMX management now includes service reload and lookup, ticket and session counts with filtered listings, expired-ticket cleanup, authentication and MFA diagnostics, and principal attribute cache invalidation. Service listings also release backend resources correctly.
Palantir
The OpenID Connect service wizard now includes an advanced verifiable credentials policy section for allowed credential types and signing algorithms.
The service history endpoint can now restore a selected registered-service revision to the service registry and live service cache, while retaining its history. Palantir offers a Restore Version action in the revision table’s context menu under View Change History.
Attribute Consent
- Consent decisions are now assigned a unique identifier when they are created.
Only the JDBC store generated one; every other store recorded the decision with an identifier of
0, which is the key those stores use. LDAP and Redis therefore kept a single decision per user, and MongoDB and DynamoDB kept a single decision for the entire deployment, each new consent silently replacing the one before it. Decisions recorded by earlier versions continue to be honored. - DynamoDB consent lookups now match the service and the decision identifier for equality. They were matched as greater-than-or-equal, so consent granted to one service could answer the check for another, and revoking a single decision removed every decision whose identifier sorted at or above it.
- Redis consent lookups now treat the principal as a literal value.
Glob characters such as
*and?, and the:separator itself, were interpolated into the scan pattern, so a principal identifier that contained them could read and delete decisions that belong to other users. - Revoking consent now removes every decision it should. Against the JDBC store, revoking all decisions for a user removed nothing at all once the user had
more than one, and when several stores are configured together only the first store that reported success was
asked to delete. The REST store now sends the decision identifier as
decisionId, the parameter its documented contract defines; it previously sentid, which a conforming server reads as a request to revoke everything for that user. - A consent decision that cannot be deciphered no longer fails the login. Rotating the
cas.consent.core.cryptokeys, or a node that does not have them, produced an error that propagated out of the login flow; such a decision now counts as a mismatch, so the user is asked to consent again and the record is replaced using the current keys. - Reminder options submitted with a consent decision are now validated. A missing or unparsable value falls back on the configured
default, and a reminder that cannot be applied to a date, such as a negative amount or a time unit of
FOREVER, is rejected rather than stored and then failing every subsequent login for that user. - Consent decisions record their creation date in UTC, so a decision’s age is the same on every CAS node whatever time zone each node runs in. Dates shown on the account profile screen are labeled as UTC.
- Consent is now evaluated once per request. The activation strategy returns
the full consent query result, carrying the decision and the consentable attributes, and the login flow reuses it rather than
evaluating the attribute release policy and reading the consent store a second time to render the consent screen. Note that a Groovy
activation script must now return a
ConsentQueryResultinstead of a boolean.
Interrupt Notifications
- Following a link on a blocking interrupt no longer records the interrupt as acknowledged, and a blocking response is never skipped by interrupt tracking. Tracking cookies are now bound to the principal; cookies issued by earlier versions are ignored, so users may see an acknowledged interrupt once more.
- Interrupt notifications no longer render during passive requests (CAS
gateway, OpenID Connectprompt=none, SAML2IsPassive); CAS returns to the application without a ticket instead, as required by the respective specifications. - JSON interrupt notifications now load their policies once and reload file changes atomically, so concurrent logins can no longer skip an interrupt while the file is being re-read.
- REST interrupt notifications now read the response payload only for successful status codes; error responses no longer interrupt every login with a generic message.
Groovy Scripting
- Groovy scripts no longer abandon an execution when the script is already busy on another thread. Previously a script that stayed busy for more than five seconds caused queued executions to return no result at all, which could silently skip a multifactor authentication trigger or an acceptable usage policy check. Executions now wait for their turn.
- Bindings assigned to an inline
groovy { ... }script are now scoped to the assigning thread and to a single execution, so variables belonging to one request can no longer be observed by the next execution of that script or by an unrelated script. - An inline
groovy { ... }script that is executed without variables, such as a scripted multifactor authentication trigger, now keeps working past its first execution. The script’s variables were previously reset to an immutable map once it had run, so every later execution failed internally and produced no result. - OpenID Connect claim mappings defined as scripts no longer discard the shared Groovy script cache after every claim. Compiled scripts, and the reloading of scripts as their files change, are now retained across token requests.
- Inline scripts used by allowed attributes, pattern-matching attribute transformations and service access strategy required attributes are compiled once and served from the script cache. Previously each of these compiled a fresh script for every attribute on every request.
- The surrogate access strategy and Groovy SAML2 metadata resolution no longer compile their script, and register a new file watcher, on every request.
- The multifactor authentication principal attribute predicate compiles its Groovy class once and recompiles it only after the file changes, instead of on every authentication attempt.
- A Groovy script that fails to compile, or that throws while running, now reports that failure to the CAS component which asked for it rather than reporting no result at all. Components designed to carry on without a script result, such as mapped attribute release and the Groovy username provider, keep their existing behavior.
- A Groovy access strategy activation criteria that produces no result now fails the request with an explanation. Previously it raised an unexplained error, and treating the missing result as an inactive criteria would have granted access without evaluating the service’s required attributes.
Other Stuff
Platform & Operations
- CAS actuator endpoints that are built on Spring MVC request mappings now honor
management.endpoint.<id>.access. AREAD_ONLYdeclaration registers only the endpoint’s read mappings, so itsPOST,PUT,PATCHandDELETEmappings are no longer reachable, and aNONEdeclaration registers no mappings at all. - CloudWatch logging now avoids recursive logging initialization when reporting appender startup or delivery failures.
- Several optimizations are in place to assist with faster startup time, allowing for more components to be lazily initialized.
Build & Project
- Authentication history, theme caching and CloudWatch shutdown now use concurrent collections and explicit coordination in place of Java monitor locking.
- A large number of dependencies and libraries have been updated to their latest versions.
