mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 17:22:13 +00:00
Move Saml2 Authentication Filters
Issue gh-8819
This commit is contained in:
parent
bbac85e20b
commit
506e50bfd0
@ -85,7 +85,7 @@ final class FilterOrderRegistration {
|
|||||||
"org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter",
|
"org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter",
|
||||||
order.next());
|
order.next());
|
||||||
this.filterToOrder.put(
|
this.filterToOrder.put(
|
||||||
"org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter",
|
"org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter",
|
||||||
order.next());
|
order.next());
|
||||||
put(X509AuthenticationFilter.class, order.next());
|
put(X509AuthenticationFilter.class, order.next());
|
||||||
put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
|
put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
|
||||||
@ -93,7 +93,7 @@ final class FilterOrderRegistration {
|
|||||||
this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",
|
this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",
|
||||||
order.next());
|
order.next());
|
||||||
this.filterToOrder.put(
|
this.filterToOrder.put(
|
||||||
"org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter",
|
"org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter",
|
||||||
order.next());
|
order.next());
|
||||||
put(UsernamePasswordAuthenticationFilter.class, order.next());
|
put(UsernamePasswordAuthenticationFilter.class, order.next());
|
||||||
order.next(); // gh-8105
|
order.next(); // gh-8105
|
||||||
|
@ -37,8 +37,6 @@ import org.springframework.security.saml2.provider.service.authentication.OpenSa
|
|||||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
|
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultSaml2AuthenticationRequestContextResolver;
|
import org.springframework.security.saml2.provider.service.web.DefaultSaml2AuthenticationRequestContextResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository;
|
import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository;
|
||||||
@ -46,7 +44,9 @@ import org.springframework.security.saml2.provider.service.web.RelyingPartyRegis
|
|||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter;
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.AuthenticationConverter;
|
import org.springframework.security.web.authentication.AuthenticationConverter;
|
||||||
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
||||||
|
@ -39,8 +39,8 @@ import org.springframework.core.ResolvableType;
|
|||||||
import org.springframework.security.config.Elements;
|
import org.springframework.security.config.Elements;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
|
import org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter;
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
|
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
@ -87,7 +87,6 @@ import org.springframework.security.saml2.provider.service.registration.InMemory
|
|||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
|
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
|
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
||||||
@ -95,6 +94,7 @@ import org.springframework.security.saml2.provider.service.web.Saml2Authenticati
|
|||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||||
import org.springframework.security.web.FilterChainProxy;
|
import org.springframework.security.web.FilterChainProxy;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.AuthenticationConverter;
|
import org.springframework.security.web.authentication.AuthenticationConverter;
|
||||||
|
@ -41,7 +41,7 @@ import org.springframework.security.saml2.provider.service.registration.InMemory
|
|||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository
|
||||||
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations
|
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter
|
||||||
import org.springframework.test.web.servlet.MockMvc
|
import org.springframework.test.web.servlet.MockMvc
|
||||||
import org.springframework.test.web.servlet.get
|
import org.springframework.test.web.servlet.get
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||||
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
import org.springframework.security.saml2.credentials.Saml2X509Credential;
|
import org.springframework.security.saml2.credentials.Saml2X509Credential;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,9 +45,8 @@ public class Saml2AuthenticationToken extends AbstractAuthenticationToken {
|
|||||||
* Creates a {@link Saml2AuthenticationToken} with the provided parameters.
|
* Creates a {@link Saml2AuthenticationToken} with the provided parameters.
|
||||||
*
|
*
|
||||||
* Note that the given {@link RelyingPartyRegistration} should have all its templates
|
* Note that the given {@link RelyingPartyRegistration} should have all its templates
|
||||||
* resolved at this point. See
|
* resolved at this point. See {@link Saml2WebSsoAuthenticationFilter} for an example
|
||||||
* {@link org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter}
|
* of performing that resolution.
|
||||||
* for an example of performing that resolution.
|
|
||||||
* @param relyingPartyRegistration the resolved {@link RelyingPartyRegistration} to
|
* @param relyingPartyRegistration the resolved {@link RelyingPartyRegistration} to
|
||||||
* use
|
* use
|
||||||
* @param saml2Response the SAML 2.0 response to authenticate
|
* @param saml2Response the SAML 2.0 response to authenticate
|
||||||
@ -68,9 +68,8 @@ public class Saml2AuthenticationToken extends AbstractAuthenticationToken {
|
|||||||
* Creates a {@link Saml2AuthenticationToken} with the provided parameters
|
* Creates a {@link Saml2AuthenticationToken} with the provided parameters
|
||||||
*
|
*
|
||||||
* Note that the given {@link RelyingPartyRegistration} should have all its templates
|
* Note that the given {@link RelyingPartyRegistration} should have all its templates
|
||||||
* resolved at this point. See
|
* resolved at this point. See {@link Saml2WebSsoAuthenticationFilter} for an example
|
||||||
* {@link org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter}
|
* of performing that resolution.
|
||||||
* for an example of performing that resolution.
|
|
||||||
* @param relyingPartyRegistration the resolved {@link RelyingPartyRegistration} to
|
* @param relyingPartyRegistration the resolved {@link RelyingPartyRegistration} to
|
||||||
* use
|
* use
|
||||||
* @param saml2Response the SAML 2.0 response to authenticate
|
* @param saml2Response the SAML 2.0 response to authenticate
|
||||||
|
@ -16,130 +16,30 @@
|
|||||||
|
|
||||||
package org.springframework.security.saml2.provider.service.servlet.filter;
|
package org.springframework.security.saml2.provider.service.servlet.filter;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.AuthenticationException;
|
|
||||||
import org.springframework.security.saml2.core.Saml2Error;
|
|
||||||
import org.springframework.security.saml2.core.Saml2ErrorCodes;
|
|
||||||
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
|
|
||||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
|
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
|
|
||||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
|
||||||
import org.springframework.security.web.authentication.AuthenticationConverter;
|
import org.springframework.security.web.authentication.AuthenticationConverter;
|
||||||
import org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
|
* @deprecated Use
|
||||||
|
* {@link org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter}
|
||||||
|
* instead
|
||||||
*/
|
*/
|
||||||
public class Saml2WebSsoAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
@Deprecated
|
||||||
|
public class Saml2WebSsoAuthenticationFilter
|
||||||
|
extends org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter {
|
||||||
|
|
||||||
public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/saml2/sso/{registrationId}";
|
|
||||||
|
|
||||||
private final AuthenticationConverter authenticationConverter;
|
|
||||||
|
|
||||||
private Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository = new HttpSessionSaml2AuthenticationRequestRepository();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@code Saml2WebSsoAuthenticationFilter} authentication filter that is
|
|
||||||
* configured to use the {@link #DEFAULT_FILTER_PROCESSES_URI} processing URL
|
|
||||||
* @param relyingPartyRegistrationRepository - repository of configured SAML 2
|
|
||||||
* entities. Required.
|
|
||||||
*/
|
|
||||||
public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||||
this(relyingPartyRegistrationRepository, DEFAULT_FILTER_PROCESSES_URI);
|
super(relyingPartyRegistrationRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@code Saml2WebSsoAuthenticationFilter} authentication filter
|
|
||||||
* @param relyingPartyRegistrationRepository - repository of configured SAML 2
|
|
||||||
* entities. Required.
|
|
||||||
* @param filterProcessesUrl the processing URL, must contain a {registrationId}
|
|
||||||
* variable. Required.
|
|
||||||
*/
|
|
||||||
public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository,
|
public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository,
|
||||||
String filterProcessesUrl) {
|
String filterProcessesUrl) {
|
||||||
this(new Saml2AuthenticationTokenConverter(
|
super(relyingPartyRegistrationRepository, filterProcessesUrl);
|
||||||
(RelyingPartyRegistrationResolver) new DefaultRelyingPartyRegistrationResolver(
|
|
||||||
relyingPartyRegistrationRepository)),
|
|
||||||
filterProcessesUrl);
|
|
||||||
Assert.isTrue(filterProcessesUrl.contains("{registrationId}"),
|
|
||||||
"filterProcessesUrl must contain a {registrationId} match variable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@link Saml2WebSsoAuthenticationFilter} given the provided parameters
|
|
||||||
* @param authenticationConverter the strategy for converting an
|
|
||||||
* {@link HttpServletRequest} into an {@link Authentication}
|
|
||||||
* @param filterProcessesUrl the processing URL
|
|
||||||
* @since 5.4
|
|
||||||
*/
|
|
||||||
public Saml2WebSsoAuthenticationFilter(AuthenticationConverter authenticationConverter, String filterProcessesUrl) {
|
public Saml2WebSsoAuthenticationFilter(AuthenticationConverter authenticationConverter, String filterProcessesUrl) {
|
||||||
super(filterProcessesUrl);
|
super(authenticationConverter, filterProcessesUrl);
|
||||||
Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
|
|
||||||
Assert.hasText(filterProcessesUrl, "filterProcessesUrl must contain a URL pattern");
|
|
||||||
this.authenticationConverter = authenticationConverter;
|
|
||||||
setAllowSessionCreation(true);
|
|
||||||
setSessionAuthenticationStrategy(new ChangeSessionIdAuthenticationStrategy());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
return super.requiresAuthentication(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
|
||||||
throws AuthenticationException {
|
|
||||||
Authentication authentication = this.authenticationConverter.convert(request);
|
|
||||||
if (authentication == null) {
|
|
||||||
Saml2Error saml2Error = new Saml2Error(Saml2ErrorCodes.RELYING_PARTY_REGISTRATION_NOT_FOUND,
|
|
||||||
"No relying party registration found");
|
|
||||||
throw new Saml2AuthenticationException(saml2Error);
|
|
||||||
}
|
|
||||||
setDetails(request, authentication);
|
|
||||||
this.authenticationRequestRepository.removeAuthenticationRequest(request, response);
|
|
||||||
return getAuthenticationManager().authenticate(authentication);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the given {@link Saml2AuthenticationRequestRepository} to remove the saved
|
|
||||||
* authentication request. If the {@link #authenticationConverter} is of the type
|
|
||||||
* {@link Saml2AuthenticationTokenConverter}, the
|
|
||||||
* {@link Saml2AuthenticationRequestRepository} will also be set into the
|
|
||||||
* {@link #authenticationConverter}.
|
|
||||||
* @param authenticationRequestRepository the
|
|
||||||
* {@link Saml2AuthenticationRequestRepository} to use
|
|
||||||
* @since 5.6
|
|
||||||
*/
|
|
||||||
public void setAuthenticationRequestRepository(
|
|
||||||
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {
|
|
||||||
Assert.notNull(authenticationRequestRepository, "authenticationRequestRepository cannot be null");
|
|
||||||
this.authenticationRequestRepository = authenticationRequestRepository;
|
|
||||||
setAuthenticationRequestRepositoryIntoAuthenticationConverter(authenticationRequestRepository);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setAuthenticationRequestRepositoryIntoAuthenticationConverter(
|
|
||||||
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {
|
|
||||||
if (this.authenticationConverter instanceof Saml2AuthenticationTokenConverter) {
|
|
||||||
Saml2AuthenticationTokenConverter authenticationTokenConverter = (Saml2AuthenticationTokenConverter) this.authenticationConverter;
|
|
||||||
authenticationTokenConverter.setAuthenticationRequestRepository(authenticationRequestRepository);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDetails(HttpServletRequest request, Authentication authentication) {
|
|
||||||
if (AbstractAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
|
|
||||||
Object details = this.authenticationDetailsSource.buildDetails(request);
|
|
||||||
((AbstractAuthenticationToken) authentication).setDetails(details);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,43 +16,11 @@
|
|||||||
|
|
||||||
package org.springframework.security.saml2.provider.service.servlet.filter;
|
package org.springframework.security.saml2.provider.service.servlet.filter;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.opensaml.core.Version;
|
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.security.saml2.core.Saml2ParameterNames;
|
|
||||||
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
|
|
||||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext;
|
|
||||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
||||||
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.registration.RelyingPartyRegistration;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultSaml2AuthenticationRequestContextResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher.MatchResult;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
|
||||||
import org.springframework.web.util.HtmlUtils;
|
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
|
||||||
import org.springframework.web.util.UriUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@code Filter} formulates a
|
* This {@code Filter} formulates a
|
||||||
@ -76,239 +44,27 @@ import org.springframework.web.util.UriUtils;
|
|||||||
* @author Filip Hanik
|
* @author Filip Hanik
|
||||||
* @author Josh Cummings
|
* @author Josh Cummings
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
|
* @deprecated Use
|
||||||
|
* {@link org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter}
|
||||||
|
* instead
|
||||||
*/
|
*/
|
||||||
public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter {
|
@Deprecated
|
||||||
|
public class Saml2WebSsoAuthenticationRequestFilter
|
||||||
|
extends org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter {
|
||||||
|
|
||||||
private final Saml2AuthenticationRequestResolver authenticationRequestResolver;
|
|
||||||
|
|
||||||
private Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository = new HttpSessionSaml2AuthenticationRequestRepository();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a {@link Saml2WebSsoAuthenticationRequestFilter} with the provided
|
|
||||||
* parameters
|
|
||||||
* @param relyingPartyRegistrationRepository a repository for relying party
|
|
||||||
* configurations
|
|
||||||
* @deprecated use the constructor that takes a
|
|
||||||
* {@link Saml2AuthenticationRequestFactory}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Saml2WebSsoAuthenticationRequestFilter(
|
public Saml2WebSsoAuthenticationRequestFilter(
|
||||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||||
this(new DefaultSaml2AuthenticationRequestContextResolver(
|
super(relyingPartyRegistrationRepository);
|
||||||
(RelyingPartyRegistrationResolver) new DefaultRelyingPartyRegistrationResolver(
|
|
||||||
relyingPartyRegistrationRepository)),
|
|
||||||
requestFactory());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Saml2AuthenticationRequestFactory requestFactory() {
|
|
||||||
String opensamlClassName = "org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationRequestFactory";
|
|
||||||
if (Version.getVersion().startsWith("4")) {
|
|
||||||
opensamlClassName = "org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationRequestFactory";
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return (Saml2AuthenticationRequestFactory) ClassUtils.forName(opensamlClassName, null)
|
|
||||||
.getDeclaredConstructor().newInstance();
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
throw new IllegalStateException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a {@link Saml2WebSsoAuthenticationRequestFilter} with the provided
|
|
||||||
* parameters
|
|
||||||
* @param authenticationRequestContextResolver a strategy for formulating a
|
|
||||||
* {@link Saml2AuthenticationRequestContext}
|
|
||||||
* @param authenticationRequestFactory strategy for formulating a
|
|
||||||
* <saml2:AuthnRequest>
|
|
||||||
* @since 5.4
|
|
||||||
*/
|
|
||||||
public Saml2WebSsoAuthenticationRequestFilter(
|
public Saml2WebSsoAuthenticationRequestFilter(
|
||||||
Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver,
|
Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver,
|
||||||
Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
||||||
this(new FactorySaml2AuthenticationRequestResolver(authenticationRequestContextResolver,
|
super(authenticationRequestContextResolver, authenticationRequestFactory);
|
||||||
authenticationRequestFactory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a {@link Saml2WebSsoAuthenticationRequestFilter} with the strategy for
|
|
||||||
* resolving the {@code AuthnRequest}
|
|
||||||
* @param authenticationRequestResolver the strategy for resolving the
|
|
||||||
* {@code AuthnRequest}
|
|
||||||
* @since 5.7
|
|
||||||
*/
|
|
||||||
public Saml2WebSsoAuthenticationRequestFilter(Saml2AuthenticationRequestResolver authenticationRequestResolver) {
|
public Saml2WebSsoAuthenticationRequestFilter(Saml2AuthenticationRequestResolver authenticationRequestResolver) {
|
||||||
Assert.notNull(authenticationRequestResolver, "authenticationRequestResolver cannot be null");
|
super(authenticationRequestResolver);
|
||||||
this.authenticationRequestResolver = authenticationRequestResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the given {@link Saml2AuthenticationRequestFactory} for formulating the SAML
|
|
||||||
* 2.0 AuthnRequest
|
|
||||||
* @param authenticationRequestFactory the {@link Saml2AuthenticationRequestFactory}
|
|
||||||
* to use
|
|
||||||
* @deprecated use the constructor instead
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void setAuthenticationRequestFactory(Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
|
||||||
Assert.notNull(authenticationRequestFactory, "authenticationRequestFactory cannot be null");
|
|
||||||
Assert.isInstanceOf(FactorySaml2AuthenticationRequestResolver.class, this.authenticationRequestResolver,
|
|
||||||
"You cannot supply both a Saml2AuthenticationRequestResolver and a Saml2AuthenticationRequestFactory");
|
|
||||||
((FactorySaml2AuthenticationRequestResolver) this.authenticationRequestResolver).authenticationRequestFactory = authenticationRequestFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the given {@link RequestMatcher} that activates this filter for a given request
|
|
||||||
* @param redirectMatcher the {@link RequestMatcher} to use
|
|
||||||
* @deprecated Configure the request matcher in an implementation of
|
|
||||||
* {@link Saml2AuthenticationRequestResolver} instead
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void setRedirectMatcher(RequestMatcher redirectMatcher) {
|
|
||||||
Assert.notNull(redirectMatcher, "redirectMatcher cannot be null");
|
|
||||||
Assert.isInstanceOf(FactorySaml2AuthenticationRequestResolver.class, this.authenticationRequestResolver,
|
|
||||||
"You cannot supply a Saml2AuthenticationRequestResolver and a redirect matcher");
|
|
||||||
((FactorySaml2AuthenticationRequestResolver) this.authenticationRequestResolver).redirectMatcher = redirectMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the given {@link Saml2AuthenticationRequestRepository} to save the
|
|
||||||
* authentication request
|
|
||||||
* @param authenticationRequestRepository the
|
|
||||||
* {@link Saml2AuthenticationRequestRepository} to use
|
|
||||||
* @since 5.6
|
|
||||||
*/
|
|
||||||
public void setAuthenticationRequestRepository(
|
|
||||||
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {
|
|
||||||
Assert.notNull(authenticationRequestRepository, "authenticationRequestRepository cannot be null");
|
|
||||||
this.authenticationRequestRepository = authenticationRequestRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
|
||||||
throws ServletException, IOException {
|
|
||||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestResolver.resolve(request);
|
|
||||||
if (authenticationRequest == null) {
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (authenticationRequest instanceof Saml2RedirectAuthenticationRequest) {
|
|
||||||
sendRedirect(request, response, (Saml2RedirectAuthenticationRequest) authenticationRequest);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sendPost(request, response, (Saml2PostAuthenticationRequest) authenticationRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendRedirect(HttpServletRequest request, HttpServletResponse response,
|
|
||||||
Saml2RedirectAuthenticationRequest authenticationRequest) throws IOException {
|
|
||||||
this.authenticationRequestRepository.saveAuthenticationRequest(authenticationRequest, request, response);
|
|
||||||
UriComponentsBuilder uriBuilder = UriComponentsBuilder
|
|
||||||
.fromUriString(authenticationRequest.getAuthenticationRequestUri());
|
|
||||||
addParameter(Saml2ParameterNames.SAML_REQUEST, authenticationRequest.getSamlRequest(), uriBuilder);
|
|
||||||
addParameter(Saml2ParameterNames.RELAY_STATE, authenticationRequest.getRelayState(), uriBuilder);
|
|
||||||
addParameter(Saml2ParameterNames.SIG_ALG, authenticationRequest.getSigAlg(), uriBuilder);
|
|
||||||
addParameter(Saml2ParameterNames.SIGNATURE, authenticationRequest.getSignature(), uriBuilder);
|
|
||||||
String redirectUrl = uriBuilder.build(true).toUriString();
|
|
||||||
response.sendRedirect(redirectUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addParameter(String name, String value, UriComponentsBuilder builder) {
|
|
||||||
Assert.hasText(name, "name cannot be empty or null");
|
|
||||||
if (StringUtils.hasText(value)) {
|
|
||||||
builder.queryParam(UriUtils.encode(name, StandardCharsets.ISO_8859_1),
|
|
||||||
UriUtils.encode(value, StandardCharsets.ISO_8859_1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendPost(HttpServletRequest request, HttpServletResponse response,
|
|
||||||
Saml2PostAuthenticationRequest authenticationRequest) throws IOException {
|
|
||||||
this.authenticationRequestRepository.saveAuthenticationRequest(authenticationRequest, request, response);
|
|
||||||
String html = createSamlPostRequestFormData(authenticationRequest);
|
|
||||||
response.setContentType(MediaType.TEXT_HTML_VALUE);
|
|
||||||
response.getWriter().write(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String createSamlPostRequestFormData(Saml2PostAuthenticationRequest authenticationRequest) {
|
|
||||||
String authenticationRequestUri = authenticationRequest.getAuthenticationRequestUri();
|
|
||||||
String relayState = authenticationRequest.getRelayState();
|
|
||||||
String samlRequest = authenticationRequest.getSamlRequest();
|
|
||||||
StringBuilder html = new StringBuilder();
|
|
||||||
html.append("<!DOCTYPE html>\n");
|
|
||||||
html.append("<html>\n").append(" <head>\n");
|
|
||||||
html.append(" <meta http-equiv=\"Content-Security-Policy\" ")
|
|
||||||
.append("content=\"script-src 'sha256-t+jmhLjs1ocvgaHBJsFcgznRk68d37TLtbI3NE9h7EU='\">\n");
|
|
||||||
html.append(" <meta charset=\"utf-8\" />\n");
|
|
||||||
html.append(" </head>\n");
|
|
||||||
html.append(" <body>\n");
|
|
||||||
html.append(" <noscript>\n");
|
|
||||||
html.append(" <p>\n");
|
|
||||||
html.append(" <strong>Note:</strong> Since your browser does not support JavaScript,\n");
|
|
||||||
html.append(" you must press the Continue button once to proceed.\n");
|
|
||||||
html.append(" </p>\n");
|
|
||||||
html.append(" </noscript>\n");
|
|
||||||
html.append(" \n");
|
|
||||||
html.append(" <form action=\"");
|
|
||||||
html.append(authenticationRequestUri);
|
|
||||||
html.append("\" method=\"post\">\n");
|
|
||||||
html.append(" <div>\n");
|
|
||||||
html.append(" <input type=\"hidden\" name=\"SAMLRequest\" value=\"");
|
|
||||||
html.append(HtmlUtils.htmlEscape(samlRequest));
|
|
||||||
html.append("\"/>\n");
|
|
||||||
if (StringUtils.hasText(relayState)) {
|
|
||||||
html.append(" <input type=\"hidden\" name=\"RelayState\" value=\"");
|
|
||||||
html.append(HtmlUtils.htmlEscape(relayState));
|
|
||||||
html.append("\"/>\n");
|
|
||||||
}
|
|
||||||
html.append(" </div>\n");
|
|
||||||
html.append(" <noscript>\n");
|
|
||||||
html.append(" <div>\n");
|
|
||||||
html.append(" <input type=\"submit\" value=\"Continue\"/>\n");
|
|
||||||
html.append(" </div>\n");
|
|
||||||
html.append(" </noscript>\n");
|
|
||||||
html.append(" </form>\n");
|
|
||||||
html.append(" \n");
|
|
||||||
html.append(" <script>window.onload = () => document.forms[0].submit();</script>\n");
|
|
||||||
html.append(" </body>\n");
|
|
||||||
html.append("</html>");
|
|
||||||
return html.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FactorySaml2AuthenticationRequestResolver implements Saml2AuthenticationRequestResolver {
|
|
||||||
|
|
||||||
private final Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver;
|
|
||||||
|
|
||||||
private RequestMatcher redirectMatcher = new AntPathRequestMatcher("/saml2/authenticate/{registrationId}");
|
|
||||||
|
|
||||||
private Saml2AuthenticationRequestFactory authenticationRequestFactory;
|
|
||||||
|
|
||||||
FactorySaml2AuthenticationRequestResolver(
|
|
||||||
Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver,
|
|
||||||
Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
|
||||||
Assert.notNull(authenticationRequestContextResolver, "authenticationRequestContextResolver cannot be null");
|
|
||||||
Assert.notNull(authenticationRequestFactory, "authenticationRequestFactory cannot be null");
|
|
||||||
this.authenticationRequestContextResolver = authenticationRequestContextResolver;
|
|
||||||
this.authenticationRequestFactory = authenticationRequestFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSaml2AuthenticationRequest resolve(HttpServletRequest request) {
|
|
||||||
MatchResult matcher = this.redirectMatcher.matcher(request);
|
|
||||||
if (!matcher.isMatch()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Saml2AuthenticationRequestContext context = this.authenticationRequestContextResolver.resolve(request);
|
|
||||||
if (context == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Saml2MessageBinding binding = context.getRelyingPartyRegistration().getAssertingPartyDetails()
|
|
||||||
.getSingleSignOnServiceBinding();
|
|
||||||
if (binding == Saml2MessageBinding.REDIRECT) {
|
|
||||||
return this.authenticationRequestFactory.createRedirectAuthenticationRequest(context);
|
|
||||||
}
|
|
||||||
return this.authenticationRequestFactory.createPostAuthenticationRequest(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2022 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.saml2.provider.service.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.opensaml.core.Version;
|
||||||
|
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.saml2.core.Saml2ParameterNames;
|
||||||
|
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
|
||||||
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext;
|
||||||
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
||||||
|
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.registration.RelyingPartyRegistration;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
|
import org.springframework.security.web.util.matcher.RequestMatcher.MatchResult;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
import org.springframework.web.util.HtmlUtils;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@code Filter} formulates a
|
||||||
|
* <a href="https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf">SAML 2.0
|
||||||
|
* AuthnRequest</a> (line 1968) and redirects to a configured asserting party.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It supports the <a href=
|
||||||
|
* "https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf">HTTP-Redirect</a>
|
||||||
|
* (line 520) and <a href=
|
||||||
|
* "https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf">HTTP-POST</a>
|
||||||
|
* (line 753) bindings.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* By default, this {@code Filter} responds to authentication requests at the {@code URI}
|
||||||
|
* {@code /saml2/authenticate/{registrationId}}. The {@code URI} template variable
|
||||||
|
* {@code {registrationId}} represents the
|
||||||
|
* {@link RelyingPartyRegistration#getRegistrationId() registration identifier} of the
|
||||||
|
* relying party that is used for initiating the authentication request.
|
||||||
|
*
|
||||||
|
* @author Filip Hanik
|
||||||
|
* @author Josh Cummings
|
||||||
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final Saml2AuthenticationRequestResolver authenticationRequestResolver;
|
||||||
|
|
||||||
|
private Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository = new HttpSessionSaml2AuthenticationRequestRepository();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a {@link Saml2WebSsoAuthenticationRequestFilter} with the provided
|
||||||
|
* parameters
|
||||||
|
* @param relyingPartyRegistrationRepository a repository for relying party
|
||||||
|
* configurations
|
||||||
|
* @deprecated use the constructor that takes a
|
||||||
|
* {@link Saml2AuthenticationRequestFactory}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Saml2WebSsoAuthenticationRequestFilter(
|
||||||
|
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||||
|
this(new DefaultSaml2AuthenticationRequestContextResolver(
|
||||||
|
(RelyingPartyRegistrationResolver) new DefaultRelyingPartyRegistrationResolver(
|
||||||
|
relyingPartyRegistrationRepository)),
|
||||||
|
requestFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Saml2AuthenticationRequestFactory requestFactory() {
|
||||||
|
String opensamlClassName = "org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationRequestFactory";
|
||||||
|
if (Version.getVersion().startsWith("4")) {
|
||||||
|
opensamlClassName = "org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationRequestFactory";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return (Saml2AuthenticationRequestFactory) ClassUtils.forName(opensamlClassName, null)
|
||||||
|
.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a {@link Saml2WebSsoAuthenticationRequestFilter} with the provided
|
||||||
|
* parameters
|
||||||
|
* @param authenticationRequestContextResolver a strategy for formulating a
|
||||||
|
* {@link Saml2AuthenticationRequestContext}
|
||||||
|
* @param authenticationRequestFactory strategy for formulating a
|
||||||
|
* <saml2:AuthnRequest>
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public Saml2WebSsoAuthenticationRequestFilter(
|
||||||
|
Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver,
|
||||||
|
Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
||||||
|
this(new FactorySaml2AuthenticationRequestResolver(authenticationRequestContextResolver,
|
||||||
|
authenticationRequestFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a {@link Saml2WebSsoAuthenticationRequestFilter} with the strategy for
|
||||||
|
* resolving the {@code AuthnRequest}
|
||||||
|
* @param authenticationRequestResolver the strategy for resolving the
|
||||||
|
* {@code AuthnRequest}
|
||||||
|
* @since 5.7
|
||||||
|
*/
|
||||||
|
public Saml2WebSsoAuthenticationRequestFilter(Saml2AuthenticationRequestResolver authenticationRequestResolver) {
|
||||||
|
Assert.notNull(authenticationRequestResolver, "authenticationRequestResolver cannot be null");
|
||||||
|
this.authenticationRequestResolver = authenticationRequestResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the given {@link Saml2AuthenticationRequestFactory} for formulating the SAML
|
||||||
|
* 2.0 AuthnRequest
|
||||||
|
* @param authenticationRequestFactory the {@link Saml2AuthenticationRequestFactory}
|
||||||
|
* to use
|
||||||
|
* @deprecated use the constructor instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void setAuthenticationRequestFactory(Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
||||||
|
Assert.notNull(authenticationRequestFactory, "authenticationRequestFactory cannot be null");
|
||||||
|
Assert.isInstanceOf(FactorySaml2AuthenticationRequestResolver.class, this.authenticationRequestResolver,
|
||||||
|
"You cannot supply both a Saml2AuthenticationRequestResolver and a Saml2AuthenticationRequestFactory");
|
||||||
|
((FactorySaml2AuthenticationRequestResolver) this.authenticationRequestResolver).authenticationRequestFactory = authenticationRequestFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the given {@link RequestMatcher} that activates this filter for a given request
|
||||||
|
* @param redirectMatcher the {@link RequestMatcher} to use
|
||||||
|
* @deprecated Configure the request matcher in an implementation of
|
||||||
|
* {@link Saml2AuthenticationRequestResolver} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void setRedirectMatcher(RequestMatcher redirectMatcher) {
|
||||||
|
Assert.notNull(redirectMatcher, "redirectMatcher cannot be null");
|
||||||
|
Assert.isInstanceOf(FactorySaml2AuthenticationRequestResolver.class, this.authenticationRequestResolver,
|
||||||
|
"You cannot supply a Saml2AuthenticationRequestResolver and a redirect matcher");
|
||||||
|
((FactorySaml2AuthenticationRequestResolver) this.authenticationRequestResolver).redirectMatcher = redirectMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the given {@link Saml2AuthenticationRequestRepository} to save the
|
||||||
|
* authentication request
|
||||||
|
* @param authenticationRequestRepository the
|
||||||
|
* {@link Saml2AuthenticationRequestRepository} to use
|
||||||
|
* @since 5.6
|
||||||
|
*/
|
||||||
|
public void setAuthenticationRequestRepository(
|
||||||
|
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {
|
||||||
|
Assert.notNull(authenticationRequestRepository, "authenticationRequestRepository cannot be null");
|
||||||
|
this.authenticationRequestRepository = authenticationRequestRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestResolver.resolve(request);
|
||||||
|
if (authenticationRequest == null) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (authenticationRequest instanceof Saml2RedirectAuthenticationRequest) {
|
||||||
|
sendRedirect(request, response, (Saml2RedirectAuthenticationRequest) authenticationRequest);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sendPost(request, response, (Saml2PostAuthenticationRequest) authenticationRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendRedirect(HttpServletRequest request, HttpServletResponse response,
|
||||||
|
Saml2RedirectAuthenticationRequest authenticationRequest) throws IOException {
|
||||||
|
this.authenticationRequestRepository.saveAuthenticationRequest(authenticationRequest, request, response);
|
||||||
|
UriComponentsBuilder uriBuilder = UriComponentsBuilder
|
||||||
|
.fromUriString(authenticationRequest.getAuthenticationRequestUri());
|
||||||
|
addParameter(Saml2ParameterNames.SAML_REQUEST, authenticationRequest.getSamlRequest(), uriBuilder);
|
||||||
|
addParameter(Saml2ParameterNames.RELAY_STATE, authenticationRequest.getRelayState(), uriBuilder);
|
||||||
|
addParameter(Saml2ParameterNames.SIG_ALG, authenticationRequest.getSigAlg(), uriBuilder);
|
||||||
|
addParameter(Saml2ParameterNames.SIGNATURE, authenticationRequest.getSignature(), uriBuilder);
|
||||||
|
String redirectUrl = uriBuilder.build(true).toUriString();
|
||||||
|
response.sendRedirect(redirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addParameter(String name, String value, UriComponentsBuilder builder) {
|
||||||
|
Assert.hasText(name, "name cannot be empty or null");
|
||||||
|
if (StringUtils.hasText(value)) {
|
||||||
|
builder.queryParam(UriUtils.encode(name, StandardCharsets.ISO_8859_1),
|
||||||
|
UriUtils.encode(value, StandardCharsets.ISO_8859_1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendPost(HttpServletRequest request, HttpServletResponse response,
|
||||||
|
Saml2PostAuthenticationRequest authenticationRequest) throws IOException {
|
||||||
|
this.authenticationRequestRepository.saveAuthenticationRequest(authenticationRequest, request, response);
|
||||||
|
String html = createSamlPostRequestFormData(authenticationRequest);
|
||||||
|
response.setContentType(MediaType.TEXT_HTML_VALUE);
|
||||||
|
response.getWriter().write(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createSamlPostRequestFormData(Saml2PostAuthenticationRequest authenticationRequest) {
|
||||||
|
String authenticationRequestUri = authenticationRequest.getAuthenticationRequestUri();
|
||||||
|
String relayState = authenticationRequest.getRelayState();
|
||||||
|
String samlRequest = authenticationRequest.getSamlRequest();
|
||||||
|
StringBuilder html = new StringBuilder();
|
||||||
|
html.append("<!DOCTYPE html>\n");
|
||||||
|
html.append("<html>\n").append(" <head>\n");
|
||||||
|
html.append(" <meta http-equiv=\"Content-Security-Policy\" ")
|
||||||
|
.append("content=\"script-src 'sha256-t+jmhLjs1ocvgaHBJsFcgznRk68d37TLtbI3NE9h7EU='\">\n");
|
||||||
|
html.append(" <meta charset=\"utf-8\" />\n");
|
||||||
|
html.append(" </head>\n");
|
||||||
|
html.append(" <body>\n");
|
||||||
|
html.append(" <noscript>\n");
|
||||||
|
html.append(" <p>\n");
|
||||||
|
html.append(" <strong>Note:</strong> Since your browser does not support JavaScript,\n");
|
||||||
|
html.append(" you must press the Continue button once to proceed.\n");
|
||||||
|
html.append(" </p>\n");
|
||||||
|
html.append(" </noscript>\n");
|
||||||
|
html.append(" \n");
|
||||||
|
html.append(" <form action=\"");
|
||||||
|
html.append(authenticationRequestUri);
|
||||||
|
html.append("\" method=\"post\">\n");
|
||||||
|
html.append(" <div>\n");
|
||||||
|
html.append(" <input type=\"hidden\" name=\"SAMLRequest\" value=\"");
|
||||||
|
html.append(HtmlUtils.htmlEscape(samlRequest));
|
||||||
|
html.append("\"/>\n");
|
||||||
|
if (StringUtils.hasText(relayState)) {
|
||||||
|
html.append(" <input type=\"hidden\" name=\"RelayState\" value=\"");
|
||||||
|
html.append(HtmlUtils.htmlEscape(relayState));
|
||||||
|
html.append("\"/>\n");
|
||||||
|
}
|
||||||
|
html.append(" </div>\n");
|
||||||
|
html.append(" <noscript>\n");
|
||||||
|
html.append(" <div>\n");
|
||||||
|
html.append(" <input type=\"submit\" value=\"Continue\"/>\n");
|
||||||
|
html.append(" </div>\n");
|
||||||
|
html.append(" </noscript>\n");
|
||||||
|
html.append(" </form>\n");
|
||||||
|
html.append(" \n");
|
||||||
|
html.append(" <script>window.onload = () => document.forms[0].submit();</script>\n");
|
||||||
|
html.append(" </body>\n");
|
||||||
|
html.append("</html>");
|
||||||
|
return html.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FactorySaml2AuthenticationRequestResolver implements Saml2AuthenticationRequestResolver {
|
||||||
|
|
||||||
|
private final Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver;
|
||||||
|
|
||||||
|
private RequestMatcher redirectMatcher = new AntPathRequestMatcher("/saml2/authenticate/{registrationId}");
|
||||||
|
|
||||||
|
private Saml2AuthenticationRequestFactory authenticationRequestFactory;
|
||||||
|
|
||||||
|
FactorySaml2AuthenticationRequestResolver(
|
||||||
|
Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver,
|
||||||
|
Saml2AuthenticationRequestFactory authenticationRequestFactory) {
|
||||||
|
Assert.notNull(authenticationRequestContextResolver, "authenticationRequestContextResolver cannot be null");
|
||||||
|
Assert.notNull(authenticationRequestFactory, "authenticationRequestFactory cannot be null");
|
||||||
|
this.authenticationRequestContextResolver = authenticationRequestContextResolver;
|
||||||
|
this.authenticationRequestFactory = authenticationRequestFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractSaml2AuthenticationRequest resolve(HttpServletRequest request) {
|
||||||
|
MatchResult matcher = this.redirectMatcher.matcher(request);
|
||||||
|
if (!matcher.isMatch()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Saml2AuthenticationRequestContext context = this.authenticationRequestContextResolver.resolve(request);
|
||||||
|
if (context == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Saml2MessageBinding binding = context.getRelyingPartyRegistration().getAssertingPartyDetails()
|
||||||
|
.getSingleSignOnServiceBinding();
|
||||||
|
if (binding == Saml2MessageBinding.REDIRECT) {
|
||||||
|
return this.authenticationRequestFactory.createRedirectAuthenticationRequest(context);
|
||||||
|
}
|
||||||
|
return this.authenticationRequestFactory.createPostAuthenticationRequest(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2021 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.saml2.provider.service.web.authentication;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.saml2.core.Saml2Error;
|
||||||
|
import org.springframework.security.saml2.core.Saml2ErrorCodes;
|
||||||
|
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
|
||||||
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
|
||||||
|
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||||
|
import org.springframework.security.web.authentication.AuthenticationConverter;
|
||||||
|
import org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
public class Saml2WebSsoAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||||
|
|
||||||
|
public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/saml2/sso/{registrationId}";
|
||||||
|
|
||||||
|
private final AuthenticationConverter authenticationConverter;
|
||||||
|
|
||||||
|
private Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository = new HttpSessionSaml2AuthenticationRequestRepository();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@code Saml2WebSsoAuthenticationFilter} authentication filter that is
|
||||||
|
* configured to use the {@link #DEFAULT_FILTER_PROCESSES_URI} processing URL
|
||||||
|
* @param relyingPartyRegistrationRepository - repository of configured SAML 2
|
||||||
|
* entities. Required.
|
||||||
|
*/
|
||||||
|
public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||||
|
this(relyingPartyRegistrationRepository, DEFAULT_FILTER_PROCESSES_URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@code Saml2WebSsoAuthenticationFilter} authentication filter
|
||||||
|
* @param relyingPartyRegistrationRepository - repository of configured SAML 2
|
||||||
|
* entities. Required.
|
||||||
|
* @param filterProcessesUrl the processing URL, must contain a {registrationId}
|
||||||
|
* variable. Required.
|
||||||
|
*/
|
||||||
|
public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository,
|
||||||
|
String filterProcessesUrl) {
|
||||||
|
this(new Saml2AuthenticationTokenConverter(
|
||||||
|
(RelyingPartyRegistrationResolver) new DefaultRelyingPartyRegistrationResolver(
|
||||||
|
relyingPartyRegistrationRepository)),
|
||||||
|
filterProcessesUrl);
|
||||||
|
Assert.isTrue(filterProcessesUrl.contains("{registrationId}"),
|
||||||
|
"filterProcessesUrl must contain a {registrationId} match variable");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link Saml2WebSsoAuthenticationFilter} given the provided parameters
|
||||||
|
* @param authenticationConverter the strategy for converting an
|
||||||
|
* {@link HttpServletRequest} into an {@link Authentication}
|
||||||
|
* @param filterProcessesUrl the processing URL
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public Saml2WebSsoAuthenticationFilter(AuthenticationConverter authenticationConverter, String filterProcessesUrl) {
|
||||||
|
super(filterProcessesUrl);
|
||||||
|
Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
|
||||||
|
Assert.hasText(filterProcessesUrl, "filterProcessesUrl must contain a URL pattern");
|
||||||
|
this.authenticationConverter = authenticationConverter;
|
||||||
|
setAllowSessionCreation(true);
|
||||||
|
setSessionAuthenticationStrategy(new ChangeSessionIdAuthenticationStrategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return super.requiresAuthentication(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws AuthenticationException {
|
||||||
|
Authentication authentication = this.authenticationConverter.convert(request);
|
||||||
|
if (authentication == null) {
|
||||||
|
Saml2Error saml2Error = new Saml2Error(Saml2ErrorCodes.RELYING_PARTY_REGISTRATION_NOT_FOUND,
|
||||||
|
"No relying party registration found");
|
||||||
|
throw new Saml2AuthenticationException(saml2Error);
|
||||||
|
}
|
||||||
|
setDetails(request, authentication);
|
||||||
|
this.authenticationRequestRepository.removeAuthenticationRequest(request, response);
|
||||||
|
return getAuthenticationManager().authenticate(authentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the given {@link Saml2AuthenticationRequestRepository} to remove the saved
|
||||||
|
* authentication request. If the {@link #authenticationConverter} is of the type
|
||||||
|
* {@link Saml2AuthenticationTokenConverter}, the
|
||||||
|
* {@link Saml2AuthenticationRequestRepository} will also be set into the
|
||||||
|
* {@link #authenticationConverter}.
|
||||||
|
* @param authenticationRequestRepository the
|
||||||
|
* {@link Saml2AuthenticationRequestRepository} to use
|
||||||
|
* @since 5.6
|
||||||
|
*/
|
||||||
|
public void setAuthenticationRequestRepository(
|
||||||
|
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {
|
||||||
|
Assert.notNull(authenticationRequestRepository, "authenticationRequestRepository cannot be null");
|
||||||
|
this.authenticationRequestRepository = authenticationRequestRepository;
|
||||||
|
setAuthenticationRequestRepositoryIntoAuthenticationConverter(authenticationRequestRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAuthenticationRequestRepositoryIntoAuthenticationConverter(
|
||||||
|
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {
|
||||||
|
if (this.authenticationConverter instanceof Saml2AuthenticationTokenConverter) {
|
||||||
|
Saml2AuthenticationTokenConverter authenticationTokenConverter = (Saml2AuthenticationTokenConverter) this.authenticationConverter;
|
||||||
|
authenticationTokenConverter.setAuthenticationRequestRepository(authenticationRequestRepository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDetails(HttpServletRequest request, Authentication authentication) {
|
||||||
|
if (AbstractAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
|
||||||
|
Object details = this.authenticationDetailsSource.buildDetails(request);
|
||||||
|
((AbstractAuthenticationToken) authentication).setDetails(details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import org.springframework.security.saml2.core.Saml2X509Credential;
|
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||||
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
|
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ package org.springframework.security.saml2.provider.service.registration;
|
|||||||
|
|
||||||
import org.springframework.security.saml2.credentials.Saml2X509Credential;
|
import org.springframework.security.saml2.credentials.Saml2X509Credential;
|
||||||
import org.springframework.security.saml2.credentials.TestSaml2X509Credentials;
|
import org.springframework.security.saml2.credentials.TestSaml2X509Credentials;
|
||||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preconfigured test data for {@link RelyingPartyRegistration} objects
|
* Preconfigured test data for {@link RelyingPartyRegistration} objects
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.saml2.provider.service.servlet.filter;
|
package org.springframework.security.saml2.provider.service.web;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -41,11 +41,6 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP
|
|||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
||||||
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
|
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.DefaultSaml2AuthenticationRequestContextResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.security.saml2.provider.service.servlet.filter;
|
package org.springframework.security.saml2.provider.service.web.authentication;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user