Skip to content

Commit 953c929

Browse files
committed
Initial SAML Deprecation Preparation Steps
- Stop using Converter constructors - Replace Saml2AuthenticationRequestContextResolver and Saml2AuthenticationRequestFactory with Saml2AuthenticationRequestResolver Issue gh-11077
1 parent ba8f344 commit 953c929

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

docs/modules/ROOT/pages/migration.adoc

+109
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,115 @@ public class SecurityConfig {
18641864
----
18651865
====
18661866

1867+
=== Stop Using SAML 2.0 `Converter` constructors
1868+
1869+
In an early release of Spring Security's SAML 2.0 support, `Saml2MetadataFilter` and `Saml2AuthenticationTokenConverter` shipped with constructors of type `Converter`.
1870+
This level of abstraction made it tricky to evolve the class and so a dedicated interface `RelyingPartyRegistrationResolver` was introduced in a later release.
1871+
1872+
In 6.0, the `Converter` constructors are removed.
1873+
To prepare for this in 5.8, change classes that implement `Converter<HttpServletRequest, RelyingPartyRegistration>` to instead implement `RelyingPartyRegistrationResolver`.
1874+
1875+
=== Change to Using `Saml2AuthenticationRequestResolver`
1876+
1877+
`Saml2AuthenticationContextResolver` and `Saml2AuthenticationRequestFactory` are removed in 6.0 as is the `Saml2WebSsoAuthenticationRequestFilter` that requires them.
1878+
They are replaced by `Saml2AuthenticationRequestResolver` and a new constructor in `Saml2WebSsoAuthenticationRequestFilter`.
1879+
The new interface removes an unnecessary transport object between the two classes.
1880+
1881+
Most applications need do nothing; however, if you use or configure `Saml2AuthenticationRequestContextResolver` or `Saml2AuthenticationRequestFactory`, try the following steps to convert instead use `Saml2AuthenticationRequestResolver`.
1882+
1883+
==== Use `setAuthnRequestCustomizer` instead of `setAuthenticationRequestContextConverter`
1884+
1885+
If you are calling `OpenSaml4AuthenticationReqeustFactory#setAuthenticationRequestContextConverter`, for example, like so:
1886+
1887+
====
1888+
.Java
1889+
[source,java,role="primary"]
1890+
----
1891+
@Bean
1892+
Saml2AuthenticationRequestFactory authenticationRequestFactory() {
1893+
OpenSaml4AuthenticationRequestFactory factory = new OpenSaml4AuthenticationRequestFactory();
1894+
factory.setAuthenticationRequestContextConverter((context) -> {
1895+
AuthnRequestBuilder authnRequestBuilder = ConfigurationService.get(XMLObjectProviderRegistry.class)
1896+
.getBuilderFactory().getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
1897+
IssuerBuilder issuerBuilder = ConfigurationService.get(XMLObjectProviderRegistry.class)
1898+
.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
1899+
tring issuer = context.getIssuer();
1900+
String destination = context.getDestination();
1901+
String assertionConsumerServiceUrl = context.getAssertionConsumerServiceUrl();
1902+
String protocolBinding = context.getRelyingPartyRegistration().getAssertionConsumerServiceBinding().getUrn();
1903+
AuthnRequest auth = authnRequestBuilder.buildObject();
1904+
auth.setID("ARQ" + UUID.randomUUID().toString().substring(1));
1905+
auth.setIssueInstant(Instant.now());
1906+
auth.setForceAuthn(Boolean.TRUE);
1907+
auth.setIsPassive(Boolean.FALSE);
1908+
auth.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
1909+
Issuer iss = issuerBuilder.buildObject();
1910+
iss.setValue(issuer);
1911+
auth.setIssuer(iss);
1912+
auth.setDestination(destination);
1913+
auth.setAssertionConsumerServiceURL(assertionConsumerServiceUrl);
1914+
});
1915+
return factory;
1916+
}
1917+
----
1918+
====
1919+
1920+
to ensure that ForceAuthn is set to `true`, you can instead do:
1921+
1922+
====
1923+
.Java
1924+
[source,java,role="primary"]
1925+
----
1926+
@Bean
1927+
Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationResolver registrations) {
1928+
OpenSaml4AuthenticationRequestResolver reaolver = new OpenSaml4AuthenticationRequestResolver(registrations);
1929+
resolver.setAuthnRequestCustomizer((context) -> context.getAuthnRequest().setForceAuthn(Boolean.TRUE));
1930+
return resolver;
1931+
}
1932+
----
1933+
====
1934+
1935+
Also, since `setAuthnRequestCustomizer` has direct access to the `HttpServletRequest`, there is no need for a `Saml2AuthenticationRequestContextResolver`.
1936+
Simply use `setAuthnRequestCustomizer` to read directly from `HttpServletRequest` this information you need.
1937+
1938+
==== Use `setAuthnRequestCustomizer` instead of `setProtocolBinding`
1939+
1940+
Instead of doing:
1941+
1942+
====
1943+
.Java
1944+
[source,java,role="primary"]
1945+
----
1946+
@Bean
1947+
Saml2AuthenticationRequestFactory authenticationRequestFactory() {
1948+
OpenSaml4AuthenticationRequestFactory factory = new OpenSaml4AuthenticationRequestFactory();
1949+
factory.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")
1950+
return factory;
1951+
}
1952+
----
1953+
====
1954+
1955+
you can do:
1956+
1957+
====
1958+
.Java
1959+
[source,java,role="primary"]
1960+
----
1961+
@Bean
1962+
Saml2AuthenticationRequestResolver authenticationRequestResolver() {
1963+
OpenSaml4AuthenticationRequestResolver reaolver = new OpenSaml4AuthenticationRequestResolver(registrations);
1964+
resolver.setAuthnRequestCustomizer((context) -> context.getAuthnRequest()
1965+
.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"));
1966+
return resolver;
1967+
}
1968+
----
1969+
====
1970+
1971+
[NOTE]
1972+
====
1973+
Since Spring Security only supports the `POST` binding for authentication, there is not very much value in overriding the protocol binding at this point in time.
1974+
====
1975+
18671976
== Reactive
18681977

18691978
=== Use `AuthorizationManager` for Method Security

0 commit comments

Comments
 (0)