Rework Saml2 Authentication Statement
This commit separates the authentication principal, the assertion details, and the relying party tenant into separate components. This allows the principal to be completely decoupled from how Spring Security triggers and processes SLO. Specifically, it adds Saml2AssertionAuthentication, a new authentication implementation that allows an Object principal and a Saml2ResponseAssertionAccessor credential. It also moves the relying party registration id from Saml2AuthenticatedPrincipal to Saml2AssertionAuthentication. As such, Saml2AuthenticatedPrincipal is now deprecated in favor of placing its assertion components in Saml2ResponseAssertionAccessor and the relying party registration id in Saml2AssertionAuthentication. Closes gh-10820
This commit is contained in:
@@ -33,7 +33,9 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt
|
||||
import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationInfo;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2ResponseAssertionAccessor;
|
||||
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml4LogoutRequestValidator;
|
||||
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml4LogoutResponseValidator;
|
||||
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml5LogoutRequestValidator;
|
||||
@@ -531,7 +533,16 @@ public final class Saml2LogoutConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
return Saml2AuthenticationInfo.fromAuthentication(authentication) != null;
|
||||
if (authentication == null) {
|
||||
return false;
|
||||
}
|
||||
if (authentication.getPrincipal() instanceof Saml2AuthenticatedPrincipal) {
|
||||
return true;
|
||||
}
|
||||
if (authentication.getCredentials() instanceof Saml2ResponseAssertionAccessor) {
|
||||
return true;
|
||||
}
|
||||
return authentication instanceof Saml2Authentication;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationInfo;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2ResponseAssertionAccessor;
|
||||
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutRequestFilter;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutResponseFilter;
|
||||
@@ -236,7 +238,16 @@ final class Saml2LogoutBeanDefinitionParser implements BeanDefinitionParser {
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
return Saml2AuthenticationInfo.fromAuthentication(authentication) != null;
|
||||
if (authentication == null) {
|
||||
return false;
|
||||
}
|
||||
if (authentication.getPrincipal() instanceof Saml2AuthenticatedPrincipal) {
|
||||
return true;
|
||||
}
|
||||
if (authentication.getCredentials() instanceof Saml2ResponseAssertionAccessor) {
|
||||
return true;
|
||||
}
|
||||
return authentication instanceof Saml2Authentication;
|
||||
}
|
||||
|
||||
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
|
||||
|
||||
@@ -170,11 +170,14 @@ import org.springframework.security.saml2.core.Saml2Error;
|
||||
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||
import org.springframework.security.saml2.credentials.TestSaml2X509Credentials;
|
||||
import org.springframework.security.saml2.provider.service.authentication.DefaultSaml2AuthenticatedPrincipal;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AssertionAuthentication;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2PostAuthenticationRequest;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2RedirectAuthenticationRequest;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2ResponseAssertion;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2ResponseAssertionAccessor;
|
||||
import org.springframework.security.saml2.provider.service.authentication.TestSaml2AuthenticationTokens;
|
||||
import org.springframework.security.saml2.provider.service.authentication.TestSaml2Authentications;
|
||||
import org.springframework.security.saml2.provider.service.authentication.TestSaml2LogoutRequests;
|
||||
@@ -520,8 +523,16 @@ final class SerializationSamples {
|
||||
generatorByClassName.put(Saml2Exception.class, (r) -> new Saml2Exception("message", new IOException("fail")));
|
||||
generatorByClassName.put(DefaultSaml2AuthenticatedPrincipal.class,
|
||||
(r) -> TestSaml2Authentications.authentication().getPrincipal());
|
||||
generatorByClassName.put(Saml2Authentication.class,
|
||||
(r) -> applyDetails(TestSaml2Authentications.authentication()));
|
||||
Saml2Authentication saml2 = TestSaml2Authentications.authentication();
|
||||
generatorByClassName.put(Saml2Authentication.class, (r) -> applyDetails(saml2));
|
||||
Saml2ResponseAssertionAccessor assertion = Saml2ResponseAssertion.withResponseValue("response")
|
||||
.nameId("name")
|
||||
.sessionIndexes(List.of("id"))
|
||||
.attributes(Map.of("key", List.of("value")))
|
||||
.build();
|
||||
generatorByClassName.put(Saml2ResponseAssertion.class, (r) -> assertion);
|
||||
generatorByClassName.put(Saml2AssertionAuthentication.class, (r) -> applyDetails(
|
||||
new Saml2AssertionAuthentication(assertion, authentication.getAuthorities(), "id")));
|
||||
generatorByClassName.put(Saml2PostAuthenticationRequest.class,
|
||||
(r) -> TestSaml2PostAuthenticationRequests.create());
|
||||
generatorByClassName.put(Saml2RedirectAuthenticationRequest.class,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user