Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 77892d571f | |||
| 06026684e5 | |||
| c3d45ae529 | |||
| acf19c1f1f | |||
| b3c880cc24 | |||
| 33d96d574f | |||
| b64d5af9c4 | |||
| 002dbf355a | |||
| 7d5414b349 | |||
| 2de2e3803a | |||
| 43a2fbf5ad | |||
| d6b295ba2c | |||
| 211fa52649 | |||
| 7f410ce5b4 | |||
| a3f6825f9c | |||
| ea0ec9e662 | |||
| 2e9e5d0555 | |||
| 92161aae2e | |||
| 3ffda83ba1 | |||
| d44923f64e | |||
| 15faf0f621 | |||
| a9f8a23e50 | |||
| 643a3f1206 | |||
| 7aafe2ed5a | |||
| ce90b85945 | |||
| 87888d42fc | |||
| e528923878 |
@@ -79,7 +79,7 @@ jobs:
|
||||
env:
|
||||
STRUCTURE101_LICENSEID: ${{ secrets.STRUCTURE101_LICENSEID }}
|
||||
run: |
|
||||
./gradlew check s101 -Ps101.licenseId="$STRUCTURE101_LICENSEID" --stacktrace
|
||||
./gradlew assemble && ./gradlew s101 -Ps101.licenseId="$STRUCTURE101_LICENSEID" --stacktrace
|
||||
deploy-artifacts:
|
||||
name: Deploy Artifacts
|
||||
needs: [ build, test, check-samples, check-tangles ]
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
send-notification:
|
||||
name: Send Notification
|
||||
needs: [ perform-release ]
|
||||
if: ${{ failure() || cancelled() }}
|
||||
if: ${{ !success() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send Notification
|
||||
|
||||
@@ -50,7 +50,7 @@ public class S101Plugin implements Plugin<Project> {
|
||||
|
||||
private void configure(JavaExec exec) {
|
||||
exec.setDescription("Runs Structure101 headless analysis, installing and configuring if necessary");
|
||||
exec.dependsOn("check");
|
||||
exec.dependsOn("assemble");
|
||||
Project project = exec.getProject();
|
||||
S101PluginExtension extension = project.getExtensions().getByType(S101PluginExtension.class);
|
||||
exec
|
||||
|
||||
+22
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -98,6 +98,10 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
|
||||
private AuthorizationCodeGrantConfigurer authorizationCodeGrantConfigurer = new AuthorizationCodeGrantConfigurer();
|
||||
|
||||
private ClientRegistrationRepository clientRegistrationRepository;
|
||||
|
||||
private OAuth2AuthorizedClientRepository authorizedClientRepository;
|
||||
|
||||
/**
|
||||
* Sets the repository of client registrations.
|
||||
* @param clientRegistrationRepository the repository of client registrations
|
||||
@@ -107,6 +111,7 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
ClientRegistrationRepository clientRegistrationRepository) {
|
||||
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
|
||||
this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository);
|
||||
this.clientRegistrationRepository = clientRegistrationRepository;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -119,6 +124,7 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
OAuth2AuthorizedClientRepository authorizedClientRepository) {
|
||||
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
|
||||
this.getBuilder().setSharedObject(OAuth2AuthorizedClientRepository.class, authorizedClientRepository);
|
||||
this.authorizedClientRepository = authorizedClientRepository;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -283,8 +289,7 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
if (this.authorizationRequestResolver != null) {
|
||||
return this.authorizationRequestResolver;
|
||||
}
|
||||
ClientRegistrationRepository clientRegistrationRepository = OAuth2ClientConfigurerUtils
|
||||
.getClientRegistrationRepository(getBuilder());
|
||||
ClientRegistrationRepository clientRegistrationRepository = getClientRegistrationRepository(getBuilder());
|
||||
return new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository,
|
||||
OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI);
|
||||
}
|
||||
@@ -292,8 +297,8 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
private OAuth2AuthorizationCodeGrantFilter createAuthorizationCodeGrantFilter(B builder) {
|
||||
AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class);
|
||||
OAuth2AuthorizationCodeGrantFilter authorizationCodeGrantFilter = new OAuth2AuthorizationCodeGrantFilter(
|
||||
OAuth2ClientConfigurerUtils.getClientRegistrationRepository(builder),
|
||||
OAuth2ClientConfigurerUtils.getAuthorizedClientRepository(builder), authenticationManager);
|
||||
getClientRegistrationRepository(builder), getAuthorizedClientRepository(builder),
|
||||
authenticationManager);
|
||||
if (this.authorizationRequestRepository != null) {
|
||||
authorizationCodeGrantFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository);
|
||||
}
|
||||
@@ -315,6 +320,18 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
return (bean != null) ? bean : new DefaultAuthorizationCodeTokenResponseClient();
|
||||
}
|
||||
|
||||
private ClientRegistrationRepository getClientRegistrationRepository(B builder) {
|
||||
return (OAuth2ClientConfigurer.this.clientRegistrationRepository != null)
|
||||
? OAuth2ClientConfigurer.this.clientRegistrationRepository
|
||||
: OAuth2ClientConfigurerUtils.getClientRegistrationRepository(builder);
|
||||
}
|
||||
|
||||
private OAuth2AuthorizedClientRepository getAuthorizedClientRepository(B builder) {
|
||||
return (OAuth2ClientConfigurer.this.authorizedClientRepository != null)
|
||||
? OAuth2ClientConfigurer.this.authorizedClientRepository
|
||||
: OAuth2ClientConfigurerUtils.getAuthorizedClientRepository(builder);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getBeanOrNull(ResolvableType type) {
|
||||
ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
|
||||
|
||||
+20
-7
@@ -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.
|
||||
@@ -172,6 +172,10 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
|
||||
private String loginProcessingUrl = OAuth2LoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI;
|
||||
|
||||
private ClientRegistrationRepository clientRegistrationRepository;
|
||||
|
||||
private OAuth2AuthorizedClientRepository authorizedClientRepository;
|
||||
|
||||
/**
|
||||
* Sets the repository of client registrations.
|
||||
* @param clientRegistrationRepository the repository of client registrations
|
||||
@@ -181,6 +185,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
ClientRegistrationRepository clientRegistrationRepository) {
|
||||
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
|
||||
this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository);
|
||||
this.clientRegistrationRepository = clientRegistrationRepository;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -194,6 +199,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
OAuth2AuthorizedClientRepository authorizedClientRepository) {
|
||||
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
|
||||
this.getBuilder().setSharedObject(OAuth2AuthorizedClientRepository.class, authorizedClientRepository);
|
||||
this.authorizedClientRepository = authorizedClientRepository;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -339,8 +345,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
@Override
|
||||
public void init(B http) throws Exception {
|
||||
OAuth2LoginAuthenticationFilter authenticationFilter = new OAuth2LoginAuthenticationFilter(
|
||||
OAuth2ClientConfigurerUtils.getClientRegistrationRepository(this.getBuilder()),
|
||||
OAuth2ClientConfigurerUtils.getAuthorizedClientRepository(this.getBuilder()), this.loginProcessingUrl);
|
||||
this.getClientRegistrationRepository(), this.getAuthorizedClientRepository(), this.loginProcessingUrl);
|
||||
authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
this.setAuthenticationFilter(authenticationFilter);
|
||||
super.loginProcessingUrl(this.loginProcessingUrl);
|
||||
@@ -406,8 +411,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
authorizationRequestBaseUri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
|
||||
}
|
||||
authorizationRequestFilter = new OAuth2AuthorizationRequestRedirectFilter(
|
||||
OAuth2ClientConfigurerUtils.getClientRegistrationRepository(this.getBuilder()),
|
||||
authorizationRequestBaseUri);
|
||||
this.getClientRegistrationRepository(), authorizationRequestBaseUri);
|
||||
}
|
||||
if (this.authorizationEndpointConfig.authorizationRequestRepository != null) {
|
||||
authorizationRequestFilter
|
||||
@@ -439,6 +443,16 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
return new AntPathRequestMatcher(loginProcessingUrl);
|
||||
}
|
||||
|
||||
private ClientRegistrationRepository getClientRegistrationRepository() {
|
||||
return (this.clientRegistrationRepository != null) ? this.clientRegistrationRepository
|
||||
: OAuth2ClientConfigurerUtils.getClientRegistrationRepository(this.getBuilder());
|
||||
}
|
||||
|
||||
private OAuth2AuthorizedClientRepository getAuthorizedClientRepository() {
|
||||
return (this.authorizedClientRepository != null) ? this.authorizedClientRepository
|
||||
: OAuth2ClientConfigurerUtils.getAuthorizedClientRepository(this.getBuilder());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private JwtDecoderFactory<ClientRegistration> getJwtDecoderFactoryBean() {
|
||||
ResolvableType type = ResolvableType.forClassWithGenerics(JwtDecoderFactory.class, ClientRegistration.class);
|
||||
@@ -529,8 +543,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, String> getLoginLinks() {
|
||||
Iterable<ClientRegistration> clientRegistrations = null;
|
||||
ClientRegistrationRepository clientRegistrationRepository = OAuth2ClientConfigurerUtils
|
||||
.getClientRegistrationRepository(this.getBuilder());
|
||||
ClientRegistrationRepository clientRegistrationRepository = this.getClientRegistrationRepository();
|
||||
ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository).as(Iterable.class);
|
||||
if (type != ResolvableType.NONE && ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) {
|
||||
clientRegistrations = (Iterable<ClientRegistration>) clientRegistrationRepository;
|
||||
|
||||
+1
@@ -147,6 +147,7 @@ final class Saml2LogoutBeanDefinitionParser implements BeanDefinitionParser {
|
||||
BeanMetadataElement saml2LogoutRequestSuccessHandler = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(Saml2RelyingPartyInitiatedLogoutSuccessHandler.class)
|
||||
.addConstructorArgValue(logoutRequestResolver)
|
||||
.addPropertyValue("logoutRequestRepository", logoutRequestRepository)
|
||||
.getBeanDefinition();
|
||||
this.logoutFilter = BeanDefinitionBuilder.rootBeanDefinition(LogoutFilter.class)
|
||||
.addConstructorArgValue(saml2LogoutRequestSuccessHandler)
|
||||
|
||||
+92
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -75,6 +75,7 @@ import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||
@@ -285,6 +286,49 @@ public class OAuth2ClientConfigurerTests {
|
||||
verify(authorizationRedirectStrategy).sendRedirect(any(), any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureWhenOAuth2LoginBeansConfiguredThenNotShared() throws Exception {
|
||||
this.spring.register(OAuth2ClientConfigWithOAuth2Login.class).autowire();
|
||||
// Setup the Authorization Request in the session
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, this.registration1.getRegistrationId());
|
||||
// @formatter:off
|
||||
OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode()
|
||||
.authorizationUri(this.registration1.getProviderDetails().getAuthorizationUri())
|
||||
.clientId(this.registration1.getClientId())
|
||||
.redirectUri("http://localhost/client-1")
|
||||
.state("state")
|
||||
.attributes(attributes)
|
||||
.build();
|
||||
// @formatter:on
|
||||
AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository = new HttpSessionOAuth2AuthorizationRequestRepository();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, request, response);
|
||||
MockHttpSession session = (MockHttpSession) request.getSession();
|
||||
String principalName = "user1";
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken(principalName, "password");
|
||||
// @formatter:off
|
||||
MockHttpServletRequestBuilder clientRequest = get("/client-1")
|
||||
.param(OAuth2ParameterNames.CODE, "code")
|
||||
.param(OAuth2ParameterNames.STATE, "state")
|
||||
.with(authentication(authentication))
|
||||
.session(session);
|
||||
this.mockMvc.perform(clientRequest)
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(redirectedUrl("http://localhost/client-1"));
|
||||
// @formatter:on
|
||||
OAuth2AuthorizedClient authorizedClient = authorizedClientRepository
|
||||
.loadAuthorizedClient(this.registration1.getRegistrationId(), authentication, request);
|
||||
assertThat(authorizedClient).isNotNull();
|
||||
// Ensure shared objects set for OAuth2 Client are not used
|
||||
ClientRegistrationRepository clientRegistrationRepository = this.spring.getContext()
|
||||
.getBean(ClientRegistrationRepository.class);
|
||||
OAuth2AuthorizedClientRepository authorizedClientRepository = this.spring.getContext()
|
||||
.getBean(OAuth2AuthorizedClientRepository.class);
|
||||
verifyNoInteractions(clientRegistrationRepository, authorizedClientRepository);
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
@@ -362,4 +406,51 @@ public class OAuth2ClientConfigurerTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableWebMvc
|
||||
static class OAuth2ClientConfigWithOAuth2Login {
|
||||
|
||||
private final ClientRegistrationRepository clientRegistrationRepository = mock(
|
||||
ClientRegistrationRepository.class);
|
||||
|
||||
private final OAuth2AuthorizedClientRepository authorizedClientRepository = mock(
|
||||
OAuth2AuthorizedClientRepository.class);
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.authorizeHttpRequests((authorize) -> authorize
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.oauth2Client((oauth2Client) -> oauth2Client
|
||||
.clientRegistrationRepository(OAuth2ClientConfigurerTests.clientRegistrationRepository)
|
||||
.authorizedClientService(OAuth2ClientConfigurerTests.authorizedClientService)
|
||||
.authorizationCodeGrant((authorizationCode) -> authorizationCode
|
||||
.authorizationRequestResolver(authorizationRequestResolver)
|
||||
.authorizationRedirectStrategy(authorizationRedirectStrategy)
|
||||
.accessTokenResponseClient(accessTokenResponseClient)
|
||||
)
|
||||
)
|
||||
.oauth2Login((oauth2Login) -> oauth2Login
|
||||
.clientRegistrationRepository(this.clientRegistrationRepository)
|
||||
.authorizedClientRepository(this.authorizedClientRepository)
|
||||
);
|
||||
// @formatter:on
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientRegistrationRepository clientRegistrationRepository() {
|
||||
return this.clientRegistrationRepository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
OAuth2AuthorizedClientRepository authorizedClientRepository() {
|
||||
return this.authorizedClientRepository;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+67
-1
@@ -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.
|
||||
@@ -73,7 +73,9 @@ import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
|
||||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
|
||||
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
|
||||
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository;
|
||||
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository;
|
||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
|
||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||
@@ -115,6 +117,7 @@ import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.springframework.security.config.annotation.SecurityContextChangedListenerArgumentMatchers.setAuthentication;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
@@ -669,6 +672,30 @@ public class OAuth2LoginConfigurerTests {
|
||||
.collect(Collectors.toList())).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oidcLoginWhenOAuth2ClientBeansConfiguredThenNotShared() throws Exception {
|
||||
this.spring.register(OAuth2LoginConfigWithOAuth2Client.class, JwtDecoderFactoryConfig.class).autowire();
|
||||
OAuth2AuthorizationRequest authorizationRequest = createOAuth2AuthorizationRequest("openid");
|
||||
this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, this.request, this.response);
|
||||
this.request.setParameter("code", "code123");
|
||||
this.request.setParameter("state", authorizationRequest.getState());
|
||||
this.springSecurityFilterChain.doFilter(this.request, this.response, this.filterChain);
|
||||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OidcUserAuthority.class)
|
||||
.hasToString("OIDC_USER");
|
||||
|
||||
// Ensure shared objects set for OAuth2 Client are not used
|
||||
ClientRegistrationRepository clientRegistrationRepository = this.spring.getContext()
|
||||
.getBean(ClientRegistrationRepository.class);
|
||||
OAuth2AuthorizedClientRepository authorizedClientRepository = this.spring.getContext()
|
||||
.getBean(OAuth2AuthorizedClientRepository.class);
|
||||
verifyNoInteractions(clientRegistrationRepository, authorizedClientRepository);
|
||||
}
|
||||
|
||||
private void loadConfig(Class<?>... configs) {
|
||||
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
|
||||
applicationContext.register(configs);
|
||||
@@ -1192,6 +1219,45 @@ public class OAuth2LoginConfigurerTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
static class OAuth2LoginConfigWithOAuth2Client extends CommonLambdaSecurityFilterChainConfig {
|
||||
|
||||
private final ClientRegistrationRepository clientRegistrationRepository = mock(
|
||||
ClientRegistrationRepository.class);
|
||||
|
||||
private final OAuth2AuthorizedClientRepository authorizedClientRepository = mock(
|
||||
OAuth2AuthorizedClientRepository.class);
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.oauth2Login((oauth2Login) -> oauth2Login
|
||||
.clientRegistrationRepository(
|
||||
new InMemoryClientRegistrationRepository(GOOGLE_CLIENT_REGISTRATION))
|
||||
.authorizedClientRepository(new HttpSessionOAuth2AuthorizedClientRepository())
|
||||
)
|
||||
.oauth2Client((oauth2Client) -> oauth2Client
|
||||
.clientRegistrationRepository(this.clientRegistrationRepository)
|
||||
.authorizedClientRepository(this.authorizedClientRepository)
|
||||
);
|
||||
// @formatter:on
|
||||
return super.configureFilterChain(http);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientRegistrationRepository clientRegistrationRepository() {
|
||||
return this.clientRegistrationRepository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
OAuth2AuthorizedClientRepository authorizedClientRepository() {
|
||||
return this.authorizedClientRepository;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private abstract static class CommonSecurityFilterChainConfig {
|
||||
|
||||
SecurityFilterChain configureFilterChain(HttpSecurity http) throws Exception {
|
||||
|
||||
+1
@@ -484,6 +484,7 @@ public class Saml2LogoutConfigurerTests {
|
||||
verify(getBean(Saml2LogoutResponseValidator.class)).validate(any());
|
||||
}
|
||||
|
||||
// gh-11363
|
||||
@Test
|
||||
public void saml2LogoutWhenCustomLogoutRequestRepositoryThenUses() throws Exception {
|
||||
this.spring.register(Saml2LogoutComponentsConfig.class).autowire();
|
||||
|
||||
+17
@@ -63,6 +63,7 @@ import org.springframework.web.util.UriUtils;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -380,6 +381,22 @@ public class Saml2LogoutBeanDefinitionParserTests {
|
||||
verify(getBean(Saml2LogoutResponseValidator.class)).validate(any());
|
||||
}
|
||||
|
||||
// gh-11363
|
||||
@Test
|
||||
public void saml2LogoutWhenCustomLogoutRequestRepositoryThenUses() throws Exception {
|
||||
this.spring.configLocations(this.xml("CustomComponents")).autowire();
|
||||
RelyingPartyRegistration registration = this.repository.findByRegistrationId("get");
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(this.rpLogoutRequest)
|
||||
.id(this.rpLogoutRequestId)
|
||||
.relayState(this.rpLogoutRequestRelayState)
|
||||
.parameters((params) -> params.put("Signature", this.rpLogoutRequestSignature))
|
||||
.build();
|
||||
given(getBean(Saml2LogoutRequestResolver.class).resolve(any(), any())).willReturn(logoutRequest);
|
||||
this.mvc.perform(post("/logout").with(authentication(this.saml2User)).with(csrf()));
|
||||
verify(getBean(Saml2LogoutRequestRepository.class)).saveLogoutRequest(eq(logoutRequest), any(), any());
|
||||
}
|
||||
|
||||
private <T> T getBean(Class<T> clazz) {
|
||||
return this.spring.getContext().getBean(clazz);
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@
|
||||
"@antora/collector-extension": "1.0.1",
|
||||
"@asciidoctor/tabs": "1.0.0-beta.6",
|
||||
"@springio/antora-extensions": "1.14.2",
|
||||
"@springio/asciidoctor-extensions": "1.0.0-alpha.14"
|
||||
"@springio/asciidoctor-extensions": "1.0.0-alpha.16"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
springBootVersion=3.1.1
|
||||
version=6.3.6
|
||||
version=6.3.7
|
||||
samplesBranch=6.3.x
|
||||
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[versions]
|
||||
com-squareup-okhttp3 = "3.14.9"
|
||||
io-rsocket = "1.1.4"
|
||||
io-rsocket = "1.1.5"
|
||||
io-spring-javaformat = "0.0.43"
|
||||
io-spring-nohttp = "0.0.11"
|
||||
jakarta-websocket = "2.1.1"
|
||||
@@ -13,22 +13,22 @@ org-jetbrains-kotlin = "1.9.25"
|
||||
org-jetbrains-kotlinx = "1.8.1"
|
||||
org-mockito = "5.11.0"
|
||||
org-opensaml = "4.3.2"
|
||||
org-springframework = "6.1.16"
|
||||
org-springframework = "6.1.17"
|
||||
|
||||
[libraries]
|
||||
ch-qos-logback-logback-classic = "ch.qos.logback:logback-classic:1.5.12"
|
||||
ch-qos-logback-logback-classic = "ch.qos.logback:logback-classic:1.5.16"
|
||||
com-fasterxml-jackson-jackson-bom = "com.fasterxml.jackson:jackson-bom:2.17.3"
|
||||
com-google-inject-guice = "com.google.inject:guice:3.0"
|
||||
com-netflix-nebula-nebula-project-plugin = "com.netflix.nebula:nebula-project-plugin:8.2.0"
|
||||
com-nimbusds-nimbus-jose-jwt = "com.nimbusds:nimbus-jose-jwt:9.37.3"
|
||||
com-nimbusds-oauth2-oidc-sdk = "com.nimbusds:oauth2-oidc-sdk:9.43.4"
|
||||
com-nimbusds-oauth2-oidc-sdk = "com.nimbusds:oauth2-oidc-sdk:9.43.6"
|
||||
com-squareup-okhttp3-mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "com-squareup-okhttp3" }
|
||||
com-squareup-okhttp3-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "com-squareup-okhttp3" }
|
||||
com-unboundid-unboundid-ldapsdk = "com.unboundid:unboundid-ldapsdk:6.0.11"
|
||||
commons-collections = "commons-collections:commons-collections:3.2.2"
|
||||
io-micrometer-micrometer-observation = "io.micrometer:micrometer-observation:1.12.13"
|
||||
io-mockk = "io.mockk:mockk:1.13.13"
|
||||
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2023.0.13"
|
||||
io-mockk = "io.mockk:mockk:1.13.16"
|
||||
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2023.0.15"
|
||||
io-rsocket-rsocket-bom = { module = "io.rsocket:rsocket-bom", version.ref = "io-rsocket" }
|
||||
io-spring-javaformat-spring-javaformat-checkstyle = { module = "io.spring.javaformat:spring-javaformat-checkstyle", version.ref = "io-spring-javaformat" }
|
||||
io-spring-javaformat-spring-javaformat-gradle-plugin = { module = "io.spring.javaformat:spring-javaformat-gradle-plugin", version.ref = "io-spring-javaformat" }
|
||||
@@ -84,8 +84,8 @@ org-seleniumhq-selenium-selenium-support = "org.seleniumhq.selenium:selenium-sup
|
||||
org-skyscreamer-jsonassert = "org.skyscreamer:jsonassert:1.5.3"
|
||||
org-slf4j-log4j-over-slf4j = "org.slf4j:log4j-over-slf4j:1.7.36"
|
||||
org-slf4j-slf4j-api = "org.slf4j:slf4j-api:2.0.16"
|
||||
org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2024.0.7"
|
||||
org-springframework-ldap-spring-ldap-core = "org.springframework.ldap:spring-ldap-core:3.2.10"
|
||||
org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2024.0.9"
|
||||
org-springframework-ldap-spring-ldap-core = "org.springframework.ldap:spring-ldap-core:3.2.11"
|
||||
org-springframework-spring-framework-bom = { module = "org.springframework:spring-framework-bom", version.ref = "org-springframework" }
|
||||
org-synchronoss-cloud-nio-multipart-parser = "org.synchronoss.cloud:nio-multipart-parser:1.1.0"
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
|
||||
distributionSha256Sum=8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Reference in New Issue
Block a user