From 5354e4d2c56a96036914cbed6d1ae9eaf2a19273 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Mon, 28 Apr 2025 11:18:32 -0600 Subject: [PATCH] Check for Null Issuer Closes gh-16989 --- .../OpenSaml4AuthenticationProvider.java | 13 ++++++++++--- .../OpenSaml4AuthenticationProviderTests.java | 11 ++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java index 59f2585596..13987df902 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -391,7 +391,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv String inResponseTo = response.getInResponseTo(); result = result.concat(validateInResponseTo(token.getAuthenticationRequest(), inResponseTo)); - String issuer = response.getIssuer().getValue(); + String issuer = issuer(response); String destination = response.getDestination(); String location = token.getRelyingPartyRegistration().getAssertionConsumerServiceLocation(); if (StringUtils.hasText(destination) && !destination.equals(location)) { @@ -414,6 +414,13 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv }; } + private static String issuer(Response response) { + if (response.getIssuer() == null) { + return null; + } + return response.getIssuer().getValue(); + } + private static List getStatusCodes(Response response) { if (response.getStatus() == null) { return List.of(StatusCode.SUCCESS); @@ -576,7 +583,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv } private void process(Saml2AuthenticationToken token, Response response) { - String issuer = response.getIssuer().getValue(); + String issuer = issuer(response); this.logger.debug(LogMessage.format("Processing SAML response from %s", issuer)); boolean responseSigned = response.isSigned(); diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java index abe4a4549a..bb3e61519b 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -861,6 +861,15 @@ public class OpenSaml4AuthenticationProviderTests { provider.authenticate(token); } + // gh-16989 + @Test + public void authenticateWhenNullIssuerThenNoNullPointer() { + OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider(); + Response response = TestOpenSamlObjects.signedResponseWithOneAssertion((r) -> r.setIssuer(null)); + Saml2AuthenticationToken token = token(response, verifying(registration())); + assertThatExceptionOfType(Saml2AuthenticationException.class).isThrownBy(() -> provider.authenticate(token)); + } + private T build(QName qName) { return (T) XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(qName).buildObject(qName); }