spring-projects/spring-security · error · Saml2Exception

Saml2Exception wrapping DecryptionException during encrypted

Error message

Saml2Exception wrapping DecryptionException during encrypted logout-request NameID decryption

What it means

In the logout-request decryption path (OpenSaml5DecryptionConfigurer / LogoutRequest decryption component), the <EncryptedID> of a LogoutRequest is decrypted to a NameID; a DecryptionException is wrapped in Saml2Exception. Logout processing fails because the IdP-encrypted identifier cannot be recovered.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/OpenSaml5Template.java:619

						}
						catch (final DecryptionException ex) {
							throw new Saml2Exception(ex);
						}
					}
				}
			}
		}

		private void decryptLogoutRequest(LogoutRequest request) {
			if (request.getEncryptedID() != null) {
				try {
					NameID decrypted = (NameID) this.decrypter.decrypt(request.getEncryptedID());
					if (decrypted != null) {
						request.setNameID(decrypted);
					}
				}
				catch (DecryptionException ex) {
					throw new Saml2Exception(ex);
				}
			}
		}

	}

}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Ensure the decryption configurer used for logout requests registers the same decryption credentials as the response path
  2. Refresh IdP metadata so the current encryption certificate is available at logout time
  3. Test with a logout request containing a plain (unencrypted) NameID to isolate credential vs config issues
  4. Catch Saml2Exception and inspect the wrapped DecryptionException cause

Example fix

// before
OpenSamlDecryptionConfigurer.withDefaults() // logout path, no credentials bound
// after
OpenSamlDecryptionConfigurer.withDecryptionCredentials(r -> Set.of(decryptionCredential))
Defensive patterns

Strategy: try-catch

Validate before calling

if (logoutRequest.getEncryptedID() != null && decryptionCredentials.isEmpty()) throw new Saml2ConfigurationException("LogoutRequest EncryptedID but no decryption credentials");

Try / catch

try { nameId = decrypter.decrypt(request.getEncryptedID()); } catch (Saml2Exception e) { log.error("Logout NameID decryption failed", e.getCause()); rejectLogout(); }

Prevention

When it happens

Trigger: Processing a SAML Single Logout request containing <EncryptedID> where this.decrypter.decrypt(request.getEncryptedID()) fails: decryption credentials absent/mismatched, or algorithm unsupported by the decrypter configured for logout requests.

Common situations: Single Logout enabled with IdP sending encrypted NameIDs but SP only configured decryption for responses (different template/config path); logout decryption credentials not propagated in the OpenSaml5 decryption configurer; IdP rotated its encryption key before a logout request.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/ab59a20587c344b4. Report an issue: GitHub.