29 Commits

Author SHA1 Message Date
Marcus Da Coregio 9f6b38bf33 Polish SAML2 tests 2022-09-29 10:13:36 -03:00
Marcus Da Coregio 65d4b2ec4b Polish 2022-09-19 15:40:15 -03:00
Marcus Da Coregio 2eb0b65eab Add Gradle Enterprise plugin
Issue gh-94
2022-09-16 08:54:54 -03:00
Marcus Da Coregio 5a7114519c Accept gradle Terms of Service
Issue gh-94
2022-09-16 08:54:53 -03:00
Marcus Da Coregio 991e26eff6 Add new task that runs all subproject's tests 2022-09-16 08:54:53 -03:00
Josh Cummings a75deea833 Use url instead of response-url 2022-07-28 18:05:28 -06:00
Marcus Da Coregio 91ccd91eaa Fix command to run Spring Boot SAML2 samples 2022-07-28 16:17:29 -03:00
Josh Cummings eb69904f4d Simplify Saml2 Login Sample 2022-07-27 17:09:33 -06:00
Josh Cummings 57a3de019e Update Dependencies for Saml2 Login Sample 2022-07-27 17:09:33 -06:00
Rob Winch eb3ea3ded6 Update aspectj Spring Security 5.8.0-SNAPSHOT 2022-07-06 09:56:39 -05:00
Marcus Da Coregio 1e354a3587 Switch remaining jcenter() to mavenCentral() 2022-05-13 15:24:02 -06:00
Marcus Da Coregio 8de55d289d Switch from jcenter() to mavenCentral() 2022-05-13 15:23:49 -06:00
Marcus Da Coregio 5834a59ce6 Use Spring Security 5.8.0-SNAPSHOT
Issue gh-77
2022-05-12 10:05:52 -03:00
Marcus Da Coregio b67e18fb82 Add init script to be used in Spring Security CI
Issue https://github.com/spring-projects/spring-security/issues/10344
2022-05-11 16:05:03 -03:00
Steve Riesenberg dbf3fbb635 Update to Spring Authorization Server 0.2.3 2022-03-28 11:22:43 -05:00
Marcus Da Coregio a4c998ed77 Update README for SAML 2.0 samples 2022-03-28 11:00:25 -03:00
Marcus Da Coregio da6fa7a565 Re-enable SAML 2.0 samples with Okta IdP
Closes gh-55
2022-03-17 09:19:45 -03:00
Marcus Da Coregio 802311ac70 SAML 2.0 Login & Logout XML Sample
Issue gh-57
2022-03-10 12:17:21 -03:00
Eleftheria Stein 2ddf0a2fa9 Update LDAP samples to use LdapBindAuthenticationManagerFactory
Closes gh-61
2022-01-31 12:37:36 +01:00
Steve Riesenberg a19471b510 Update Spring Authorization Server to 0.2.1 2022-01-20 11:41:45 -06:00
Steve Riesenberg 73fbaa9950 Add milestone repository
Closes gh-58
2022-01-14 13:40:19 -06:00
Marcus Da Coregio 0e4e7c7373 Remove remaining usage of WebSecurityConfigurerAdapter 2021-12-15 09:22:40 -03:00
Eleftheria Stein 48e4401507 Temporarily disable tests on SAML2 samples
Issue gh-55
2021-12-13 17:36:14 +01:00
Eleftheria Stein 0e91e6300e Prevent gradle cache on tests
Closes gh-54
2021-12-13 17:04:46 +01:00
Marcus Da Coregio 0818005c46 Increase timeout for WebTestClient
Sometimes the tests fail with the message Timeout on blocking read for 5000000000 NANOSECONDS
2021-12-10 14:28:52 -03:00
Marcus Da Coregio 08166219c7 Use Spring Security 5.7.0-SNAPSHOT 2021-12-10 14:25:44 -03:00
Marcus Da Coregio 6b3e6546aa Fix broken links
Issue gh-53
2021-12-10 14:14:15 -03:00
Marcus Da Coregio 1181eb2b3d Fix broken links in README
Closes gh-53
2021-12-10 13:50:35 -03:00
Marcus Da Coregio 526bc16f7e Remove usage of WebSecurityConfigurerAdapter
Switch to expose a SecurityFilterChain Bean

Closes gh-52
2021-12-10 09:53:33 -03:00
170 changed files with 8898 additions and 807 deletions
+1 -1
View File
@@ -4,5 +4,5 @@
<component name="FrameworkDetectionExcludesConfiguration"> <component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" /> <file type="web" url="file://$PROJECT_DIR$" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="temurin-11" project-jdk-type="JavaSDK" />
</project> </project>
+23 -1
View File
@@ -20,4 +20,26 @@ allprojects {
} }
} }
} }
} }
if (hasProperty('buildScan')) {
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}
}
repositories {
mavenCentral()
}
tasks.register('runAllTests') {
var allTasks = rootProject.getAllTasks(true)
var allTestsTasks = allTasks.values().collect { t ->
t.findAll { it.name == 'test' || it.name == 'integrationTest' }
}.flatten()
it.dependsOn {
allTestsTasks
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
org.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError org.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.caching=true org.gradle.caching=true
+3 -1
View File
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class HelloTests { public class HelloTests {
@Autowired @Autowired
+3 -1
View File
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -19,4 +20,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
+2 -2
View File
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class HelloTests { public class HelloTests {
@Autowired @Autowired
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -25,4 +26,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -23,4 +24,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class HelloSecurityTests { public class HelloSecurityTests {
@Autowired @Autowired
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class HelloSecurityTests { public class HelloSecurityTests {
@Autowired @Autowired
+3 -1
View File
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -19,4 +20,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class HelloTests { public class HelloTests {
@Autowired @Autowired
+3 -1
View File
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class HelloMethodApplicationTests { public class HelloMethodApplicationTests {
@Autowired @Autowired
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -24,4 +25,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
} outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -36,7 +36,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
* @author Rob Winch * @author Rob Winch
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class OAuth2LoginApplicationTests { public class OAuth2LoginApplicationTests {
@Autowired @Autowired
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
} outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -36,7 +36,7 @@ import static org.hamcrest.Matchers.containsString;
* @since 5.1 * @since 5.1
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
@ActiveProfiles("test") @ActiveProfiles("test")
public class ServerOAuth2ResourceServerApplicationITests { public class ServerOAuth2ResourceServerApplicationITests {
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -24,4 +25,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
} outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -39,7 +39,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
@WebFluxTest @WebFluxTest
@Import({ SecurityConfiguration.class, OAuth2WebClientController.class }) @Import({ SecurityConfiguration.class, OAuth2WebClientController.class })
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class OAuth2WebClientControllerTests { public class OAuth2WebClientControllerTests {
private static MockWebServer web = new MockWebServer(); private static MockWebServer web = new MockWebServer();
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @author Rob Winch * @author Rob Winch
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class OAuth2WebClientWebFluxApplicationTests { public class OAuth2WebClientWebFluxApplicationTests {
@Autowired @Autowired
@@ -39,7 +39,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
@WebFluxTest @WebFluxTest
@Import({ SecurityConfiguration.class, RegisteredOAuth2AuthorizedClientController.class }) @Import({ SecurityConfiguration.class, RegisteredOAuth2AuthorizedClientController.class })
@AutoConfigureWebTestClient @AutoConfigureWebTestClient(timeout = "36000")
public class RegisteredOAuth2AuthorizedClientControllerTests { public class RegisteredOAuth2AuthorizedClientControllerTests {
private static MockWebServer web = new MockWebServer(); private static MockWebServer web = new MockWebServer();
@@ -1 +1 @@
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -4,17 +4,18 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
aspect platform("org.springframework:spring-framework-bom:5.3.0") aspect platform("org.springframework:spring-framework-bom:5.3.13")
aspect platform("org.springframework.security:spring-security-bom:5.4.0-SNAPSHOT") aspect platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
aspect "org.springframework.security:spring-security-aspects" aspect "org.springframework.security:spring-security-aspects"
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -31,6 +32,7 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -18,26 +18,27 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
// @formatter:off @Bean
@Override public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.antMatchers("/login", "/resources/**").permitAll() .antMatchers("/login", "/resources/**").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.jee((jee) -> jee.mappableRoles("USER", "ADMIN")); .jee((jee) -> jee.mappableRoles("USER", "ADMIN"));
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
} outputs.upToDateWhen { false }
}
@@ -18,31 +18,30 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Override @Bean
// @formatter:off public SecurityFilterChain securityFilterChain(HttpSecurity http, UserDetailsService users) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeRequests((authorize) -> authorize .authorizeRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.formLogin((form) -> form .formLogin((form) -> form
.loginPage("/login") .loginPage("/login")
.permitAll() .permitAll()
) )
.rememberMe(withDefaults()); .rememberMe((rememberMe) -> rememberMe.userDetailsService(users));
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -18,28 +18,29 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Override @Bean
// @formatter:off public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeRequests((authorize) -> authorize .authorizeRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.formLogin((form) -> form .formLogin((form) -> form
.loginPage("/login") .loginPage("/login")
.permitAll() .permitAll()
); );
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -17,14 +17,13 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
// @formatter:off // @formatter:off
@Bean @Bean
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.hsqldb:hsqldb:2.5.1" implementation "org.hsqldb:hsqldb:2.5.1"
@@ -36,4 +37,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -34,7 +34,8 @@ public class DataSourceConfiguration {
@Bean @Bean
public DataSource dataSource() { public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL).build(); return builder.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:org/springframework/security/core/userdetails/jdbc/users.ddl").build();
} }
} }
@@ -17,28 +17,27 @@ package example;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Autowired @Bean
DataSource dataSource; UserDetailsManager users(DataSource dataSource) {
UserDetails user = User.builder().username("user")
// @formatter:off .password("{bcrypt}$2a$10$AiyMWI4UBLozgXq6itzyVuxrtofjcPzn/WS3fOrcqgzdax9jB7Io.").roles("USER").build();
@Autowired UserDetails admin = User.builder().username("admin")
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { .password("{bcrypt}$2a$10$AiyMWI4UBLozgXq6itzyVuxrtofjcPzn/WS3fOrcqgzdax9jB7Io.").roles("USER", "ADMIN")
auth .build();
.jdbcAuthentication() JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
.dataSource(this.dataSource) users.createUser(user);
.withDefaultSchema() users.createUser(admin);
.withUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER")) return users;
.withUser(User.withDefaultPasswordEncoder().username("admin").password("password").roles("ADMIN", "USER"));
} }
// @formatter:on
} }
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,39 +17,29 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.ldap.core.support.BaseLdapPathContextSource; import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource; import org.springframework.security.config.ldap.EmbeddedLdapServerContextSourceFactoryBean;
import org.springframework.security.ldap.authentication.BindAuthenticator; import org.springframework.security.config.ldap.LdapBindAuthenticationManagerFactory;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider; import org.springframework.security.ldap.userdetails.PersonContextMapper;
import org.springframework.security.ldap.authentication.LdapAuthenticator;
import org.springframework.security.ldap.server.UnboundIdContainer;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { public class SecurityConfiguration {
@Bean @Bean
UnboundIdContainer ldapContainer() { public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
UnboundIdContainer result = new UnboundIdContainer("dc=springframework,dc=org", "classpath:users.ldif"); EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean = EmbeddedLdapServerContextSourceFactoryBean
result.setPort(0); .fromEmbeddedLdapServer();
return result; contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
} }
@Bean @Bean
DefaultSpringSecurityContextSource contextSource(UnboundIdContainer container) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
return new DefaultSpringSecurityContextSource( LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
"ldap://localhost:" + container.getPort() + "/dc=springframework,dc=org"); factory.setUserDnPatterns("uid={0},ou=people");
} factory.setUserDetailsContextMapper(new PersonContextMapper());
return factory.createAuthenticationManager();
@Bean
BindAuthenticator authenticator(BaseLdapPathContextSource contextSource) {
BindAuthenticator authenticator = new BindAuthenticator(contextSource);
authenticator.setUserDnPatterns(new String[] { "uid={0},ou=people" });
return authenticator;
}
@Bean
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
return new LdapAuthenticationProvider(authenticator);
} }
} }
@@ -8,13 +8,14 @@ plugins {
//apply from: "gradle/gretty.gradle" //apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -32,4 +33,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -18,27 +18,28 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Override @Bean
// @formatter:off public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.x509(withDefaults()); .x509(withDefaults());
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
+5 -3
View File
@@ -4,14 +4,15 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.data:spring-data-releasetrain:Neumann-SR5") implementation platform("org.springframework.data:spring-data-releasetrain:Neumann-SR5")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -18,28 +18,29 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Override @Bean
// @formatter:off public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.httpBasic(withDefaults()) .httpBasic(withDefaults())
.formLogin(withDefaults()); .formLogin(withDefaults());
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -18,28 +18,29 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Override @Bean
// @formatter:off public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.httpBasic(withDefaults()) .httpBasic(withDefaults())
.formLogin(withDefaults()); .formLogin(withDefaults());
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -8,13 +8,14 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0") implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -20,17 +20,35 @@ import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.sessionManagement((sessions) -> sessions
.sessionConcurrency((concurrency) -> concurrency
.maximumSessions(1)
.expiredUrl("/login?expired")
)
);
// @formatter:on
return http.build();
}
// @formatter:off // @formatter:off
@Bean @Bean
@@ -44,21 +62,4 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
} }
// @formatter:on // @formatter:on
// @formatter:off
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.sessionManagement((sessions) -> sessions
.sessionConcurrency((concurrency) -> concurrency
.maximumSessions(1)
.expiredUrl("/login?expired")
)
);
}
// @formatter:on
} }
@@ -6,45 +6,46 @@ It uses https://simplesamlphp.org/[SimpleSAMLphp] as its asserting party.
The sample application uses Spring Boot and the `spring-security-saml2-service-provider` The sample application uses Spring Boot and the `spring-security-saml2-service-provider`
module which is new in Spring Security 5.2. module which is new in Spring Security 5.2.
The https://docs.spring.io/spring-security/site/docs/5.6.0-SNAPSHOT/reference/html5/#servlet-saml2login-logout[SAML 2.0 Logout feature] is new in Spring Security 5.6. The https://docs.spring.io/spring-security/reference/servlet/saml2/logout.html[SAML 2.0 Logout feature] is new in Spring Security 5.6.
== Goals == Goals
=== SAML 2.0 Login === SAML 2.0 Login
`saml2Login()` provides a very simple implementation of a Service Provider that can receive a SAML 2.0 Response via the HTTP-POST and HTTP-REDIRECT bindings against the SimpleSAMLphp SAML 2.0 reference implementation. `saml2Login()` provides a very simple implementation of a Service Provider that can receive a SAML 2.0 Response via the HTTP-POST and HTTP-REDIRECT bindings against the https://developer.okta.com/docs/guides/build-sso-integration/saml2/main/[Okta SAML 2.0 IDP] reference implementation.
The following features are implemented in the MVP: The following features are implemented in the MVP:
1. Receive and validate a SAML 2.0 Response containing an assertion, and create a corresponding authentication in Spring Security 1. Receive and validate a SAML 2.0 Response containing an assertion, and create a corresponding authentication in Spring Security
2. Send a SAML 2.0 AuthNRequest to an Identity Provider 2. Send a SAML 2.0 AuthNRequest to an Identity Provider
3. Provide a framework for components used in SAML 2.0 authentication that can be swapped by configuration 3. Provide a framework for components used in SAML 2.0 authentication that can be swapped by configuration
4. Work against the SimpleSAMLphp reference implementation 4. Work against the Okta SAML 2.0 IDP reference implementation
=== SAML 2.0 Single Logout === SAML 2.0 Single Logout
`saml2Logout()` supports RP- and AP-initiated SAML 2.0 Single Logout via the HTTP-POST and HTTP-REDIRECT bindings against the SimpleSAMLphp SAML 2.0 reference implementation. `saml2Logout()` supports RP- and AP-initiated SAML 2.0 Single Logout via the HTTP-POST and HTTP-REDIRECT bindings against the https://developer.okta.com/docs/guides/build-sso-integration/saml2/main/[Okta SAML 2.0 IDP] reference implementation.
On this sample, the SAML 2.0 Logout is using the HTTP-POST binding. On this sample, the SAML 2.0 Logout is using the HTTP-POST binding.
You can refer to the https://docs.spring.io/spring-security/site/docs/5.6.0-SNAPSHOT/reference/html5/#servlet-saml2login-logout[reference documentation] for more details about the RP- and AP-initiated SAML 2.0 Logout. You can refer to the https://docs.spring.io/spring-security/reference/servlet/saml2/logout.html[reference documentation] for more details about the RP- and AP-initiated SAML 2.0 Logout.
== Run the Sample == Run the Sample
=== Start up the application === Start up the Sample Boot Application
```
You should run the application war in a servlet container like Tomcat ./gradlew :spring-security-samples-boot-saml2login:bootRun
```
=== Open a Browser === Open a Browser
http://localhost:8080/ http://localhost:8080/
You will be redirect to the SimpleSAMLphp IDP You will be redirect to the Okta SAML 2.0 IDP
=== Type in your credentials === Type in your credentials
``` ```
User: user User: testuser@spring.security.saml
Password: password Password: 12345678
``` ```
@@ -24,7 +24,8 @@ plugins {
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" } maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
} }
@@ -36,7 +37,7 @@ dependencies {
implementation "org.opensaml:opensaml-saml-impl:4.1.1" implementation "org.opensaml:opensaml-saml-impl:4.1.1"
} }
implementation platform("org.springframework:spring-framework-bom:5.3.11") implementation platform("org.springframework:spring-framework-bom:5.3.11")
implementation platform("org.springframework.security:spring-security-bom:5.6.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.8.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
@@ -63,4 +64,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -16,15 +16,17 @@
package example; package example;
import java.io.IOException; import java.util.ArrayList;
import java.util.List;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput; import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput; import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@@ -40,6 +42,8 @@ import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ApplicationConfiguration.class) @ContextConfiguration(classes = ApplicationConfiguration.class)
@WebAppConfiguration @WebAppConfiguration
@@ -66,35 +70,58 @@ public class Saml2JavaConfigurationITests {
@Test @Test
void authenticationAttemptWhenValidThenShowsUserEmailAddress() throws Exception { void authenticationAttemptWhenValidThenShowsUserEmailAddress() throws Exception {
HtmlPage relyingParty = performLogin(); performLogin();
Assertions.assertThat(relyingParty.asText()).contains("You're email address is testuser@spring.security.saml"); HtmlPage home = (HtmlPage) this.webClient.getCurrentWindow().getEnclosedPage();
assertThat(home.asText()).contains("You're email address is testuser@spring.security.saml");
} }
@Test @Test
void logoutWhenRelyingPartyInitiatedLogoutThenLoginPageWithLogoutParam() throws Exception { void logoutWhenRelyingPartyInitiatedLogoutThenLoginPageWithLogoutParam() throws Exception {
HtmlPage relyingParty = performLogin(); performLogin();
HtmlElement rpLogoutButton = relyingParty.getHtmlElementById("rp_logout_button"); HtmlPage home = (HtmlPage) this.webClient.getCurrentWindow().getEnclosedPage();
HtmlElement rpLogoutButton = home.getHtmlElementById("rp_logout_button");
HtmlPage loginPage = rpLogoutButton.click(); HtmlPage loginPage = rpLogoutButton.click();
Assertions.assertThat(loginPage.getUrl().getFile()).isEqualTo("/login?logout"); this.webClient.waitForBackgroundJavaScript(10000);
List<String> urls = new ArrayList<>();
urls.add(loginPage.getUrl().getFile());
urls.add(((HtmlPage) this.webClient.getCurrentWindow().getEnclosedPage()).getUrl().getFile());
assertThat(urls).withFailMessage(() -> {
// @formatter:off
String builder = loginPage.asXml()
+ "\n\n\n"
+ "Enclosing Page"
+ "\n\n\n"
+ ((HtmlPage) this.webClient.getCurrentWindow().getEnclosedPage()).asXml();
// @formatter:on
return builder;
}).contains("/login?logout");
} }
@Test private void performLogin() throws Exception {
void logoutWhenAssertingPartyInitiatedLogoutThenLoginPageWithLogoutParam() throws Exception {
HtmlPage relyingParty = performLogin();
HtmlElement apLogoutButton = relyingParty.getHtmlElementById("ap_logout_button");
HtmlPage loginPage = apLogoutButton.click();
Assertions.assertThat(loginPage.getUrl().getFile()).isEqualTo("/login?logout");
}
private HtmlPage performLogin() throws IOException {
HtmlPage login = this.webClient.getPage("/"); HtmlPage login = this.webClient.getPage("/");
HtmlForm form = login.getFormByName("f"); this.webClient.waitForBackgroundJavaScript(10000);
HtmlForm form = findForm(login);
HtmlInput username = form.getInputByName("username"); HtmlInput username = form.getInputByName("username");
HtmlInput password = form.getInputByName("password"); HtmlPasswordInput password = form.getInputByName("password");
HtmlSubmitInput submit = login.getHtmlElementById("submit_button"); HtmlSubmitInput submit = login.getHtmlElementById("okta-signin-submit");
username.setValueAttribute("user"); username.type("testuser@spring.security.saml");
password.setValueAttribute("password"); password.type("12345678");
return submit.click(); submit.click();
this.webClient.waitForBackgroundJavaScript(10000);
}
private HtmlForm findForm(HtmlPage login) {
for (HtmlForm form : login.getForms()) {
try {
if (form.getId().equals("form19")) {
return form;
}
}
catch (ElementNotFoundException ex) {
// Continue
}
}
throw new IllegalStateException("Could not resolve login form");
} }
} }
@@ -31,7 +31,7 @@ public class IndexController {
@GetMapping("/") @GetMapping("/")
public String index(Model model, @AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) { public String index(Model model, @AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
String emailAddress = principal.getFirstAttribute("emailAddress"); String emailAddress = principal.getFirstAttribute("email");
model.addAttribute("emailAddress", emailAddress); model.addAttribute("emailAddress", emailAddress);
model.addAttribute("userAttributes", principal.getAttributes()); model.addAttribute("userAttributes", principal.getAttributes());
return "index"; return "index";
@@ -32,6 +32,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.RelyingPartyRegistrations; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations;
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity @EnableWebSecurity
@@ -57,13 +58,16 @@ public class SecurityConfiguration {
@Bean @Bean
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() {
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations
.fromMetadataLocation("https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/metadata.php") .fromMetadataLocation("https://dev-05937739.okta.com/app/exk46xofd8NZvFCpS5d7/sso/saml/metadata")
.registrationId("one") .registrationId("one")
.decryptionX509Credentials( .decryptionX509Credentials(
(c) -> c.add(Saml2X509Credential.decryption(this.privateKey, relyingPartyCertificate()))) (c) -> c.add(Saml2X509Credential.decryption(this.privateKey, relyingPartyCertificate())))
.signingX509Credentials( .signingX509Credentials(
(c) -> c.add(Saml2X509Credential.signing(this.privateKey, relyingPartyCertificate()))) (c) -> c.add(Saml2X509Credential.signing(this.privateKey, relyingPartyCertificate())))
.build(); .singleLogoutServiceLocation(
"https://dev-05937739.okta.com/app/dev-05937739_springgsecuritysaml2idp_1/exk46xofd8NZvFCpS5d7/slo/saml")
.singleLogoutServiceResponseLocation("http://localhost:8080/logout/saml2/slo")
.singleLogoutServiceBinding(Saml2MessageBinding.POST).build();
return new InMemoryRelyingPartyRegistrationRepository(relyingPartyRegistration); return new InMemoryRelyingPartyRegistrationRepository(relyingPartyRegistration);
} }
@@ -36,11 +36,6 @@
</button> </button>
</form> </form>
</li> </li>
<li class="nav-item">
<a id="ap_logout_button" class="nav-link" href="https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/SingleLogoutService.php?ReturnTo=http://localhost:8080/login?logout">
AP-initiated Logout
</a>
</li>
</ul> </ul>
</div> </div>
<main role="main" class="container"> <main role="main" class="container">
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -24,4 +25,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -20,4 +21,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -23,4 +24,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -20,10 +20,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
@@ -34,19 +34,20 @@ import static org.springframework.security.config.Customizer.withDefaults;
*/ */
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
@Override @Bean
// @formatter:off public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.httpBasic(withDefaults()) .httpBasic(withDefaults())
.formLogin(withDefaults()); .formLogin(withDefaults());
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
+3 -1
View File
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -19,4 +20,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -5,7 +5,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -19,4 +20,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -31,7 +31,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer; import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
@@ -43,6 +42,7 @@ import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler; import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
/** /**
* Security configuration for the main application. * Security configuration for the main application.
@@ -50,7 +50,7 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
* @author Josh Cummings * @author Josh Cummings
*/ */
@Configuration @Configuration
public class RestConfig extends WebSecurityConfigurerAdapter { public class RestConfig {
@Value("${jwt.public.key}") @Value("${jwt.public.key}")
RSAPublicKey key; RSAPublicKey key;
@@ -58,22 +58,23 @@ public class RestConfig extends WebSecurityConfigurerAdapter {
@Value("${jwt.private.key}") @Value("${jwt.private.key}")
RSAPrivateKey priv; RSAPrivateKey priv;
@Override @Bean
protected void configure(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.csrf((csrf) -> csrf.ignoringAntMatchers("/token")) .csrf((csrf) -> csrf.ignoringAntMatchers("/token"))
.httpBasic(Customizer.withDefaults()) .httpBasic(Customizer.withDefaults())
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt) .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling((exceptions) -> exceptions .exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()) .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler()) .accessDeniedHandler(new BearerTokenAccessDeniedHandler())
); );
// @formatter:on // @formatter:on
return http.build();
} }
@Bean @Bean
@@ -16,10 +16,12 @@
package example.web; package example.web;
import example.RestConfig;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
@@ -35,6 +37,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Josh Cummings * @author Josh Cummings
*/ */
@WebMvcTest({ HelloController.class, TokenController.class }) @WebMvcTest({ HelloController.class, TokenController.class })
@Import(RestConfig.class)
public class HelloControllerTests { public class HelloControllerTests {
@Autowired @Autowired
+3 -1
View File
@@ -5,7 +5,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,13 +18,10 @@ package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.support.BaseLdapPathContextSource; import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.ldap.authentication.BindAuthenticator; import org.springframework.security.config.ldap.EmbeddedLdapServerContextSourceFactoryBean;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider; import org.springframework.security.config.ldap.LdapBindAuthenticationManagerFactory;
import org.springframework.security.ldap.authentication.LdapAuthenticator;
import org.springframework.security.ldap.server.UnboundIdContainer;
import org.springframework.security.ldap.userdetails.PersonContextMapper; import org.springframework.security.ldap.userdetails.PersonContextMapper;
/** /**
@@ -36,30 +33,19 @@ import org.springframework.security.ldap.userdetails.PersonContextMapper;
public class SecurityConfig { public class SecurityConfig {
@Bean @Bean
UnboundIdContainer ldapContainer() { public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
UnboundIdContainer container = new UnboundIdContainer("dc=springframework,dc=org", "classpath:users.ldif"); EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean = EmbeddedLdapServerContextSourceFactoryBean
container.setPort(0); .fromEmbeddedLdapServer();
return container; contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
} }
@Bean @Bean
ContextSource contextSource(UnboundIdContainer container) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
int port = container.getPort(); LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
return new DefaultSpringSecurityContextSource("ldap://localhost:" + port + "/dc=springframework,dc=org"); factory.setUserDnPatterns("uid={0},ou=people");
} factory.setUserDetailsContextMapper(new PersonContextMapper());
return factory.createAuthenticationManager();
@Bean
BindAuthenticator authenticator(BaseLdapPathContextSource contextSource) {
BindAuthenticator authenticator = new BindAuthenticator(contextSource);
authenticator.setUserDnPatterns(new String[] { "uid={0},ou=people" });
return authenticator;
}
@Bean
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
provider.setUserDetailsContextMapper(new PersonContextMapper());
return provider;
} }
} }
@@ -6,13 +6,14 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.security:spring-security-oauth2-authorization-server:0.2.0' implementation 'org.springframework.security:spring-security-oauth2-authorization-server:0.2.3'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.security:spring-security-test'
@@ -22,4 +23,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -24,4 +25,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -44,7 +44,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
@@ -63,6 +62,7 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
@@ -328,21 +328,22 @@ public class OAuth2LoginApplicationTests {
} }
@EnableWebSecurity @EnableWebSecurity
public static class SecurityTestConfig extends WebSecurityConfigurerAdapter { public static class SecurityTestConfig {
// @formatter:off @Bean
@Override public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.oauth2Login((oauth2) -> oauth2 .oauth2Login((oauth2) -> oauth2
.tokenEndpoint((token) -> token.accessTokenResponseClient(mockAccessTokenResponseClient())) .tokenEndpoint((token) -> token.accessTokenResponseClient(mockAccessTokenResponseClient()))
.userInfoEndpoint((userInfo) -> userInfo.userService(mockUserService())) .userInfoEndpoint((userInfo) -> userInfo.userService(mockUserService()))
); );
// @formatter:on
return http.build();
} }
// @formatter:on
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> mockAccessTokenResponseClient() { private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> mockAccessTokenResponseClient() {
OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("access-token-1234") OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("access-token-1234")
@@ -6,7 +6,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
} outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -20,10 +20,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
/** /**
* OAuth resource configuration. * OAuth resource configuration.
@@ -31,22 +31,23 @@ import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
* @author Josh Cummings * @author Josh Cummings
*/ */
@EnableWebSecurity @EnableWebSecurity
public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter { public class OAuth2ResourceServerSecurityConfiguration {
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}") @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwkSetUri; String jwkSetUri;
@Override @Bean
protected void configure(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.antMatchers(HttpMethod.GET, "/message/**").hasAuthority("SCOPE_message:read") .antMatchers(HttpMethod.GET, "/message/**").hasAuthority("SCOPE_message:read")
.antMatchers(HttpMethod.POST, "/message/**").hasAuthority("SCOPE_message:write") .antMatchers(HttpMethod.POST, "/message/**").hasAuthority("SCOPE_message:write")
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
// @formatter:on // @formatter:on
return http.build();
} }
@Bean @Bean
@@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
@@ -36,6 +37,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* *
*/ */
@WebMvcTest(OAuth2ResourceServerController.class) @WebMvcTest(OAuth2ResourceServerController.class)
@Import(OAuth2ResourceServerSecurityConfiguration.class)
public class OAuth2ResourceServerControllerTests { public class OAuth2ResourceServerControllerTests {
@Autowired @Autowired
@@ -22,7 +22,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
} outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.6.0-SNAPSHOT version=5.8.0-SNAPSHOT
spring-security.version=5.6.0-SNAPSHOT spring-security.version=5.8.0-SNAPSHOT
@@ -42,9 +42,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
@@ -54,7 +54,7 @@ import static org.springframework.security.config.Customizer.withDefaults;
* @author Josh Cummings * @author Josh Cummings
*/ */
@EnableWebSecurity @EnableWebSecurity
public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter { public class OAuth2ResourceServerSecurityConfiguration {
private final JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256; private final JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256;
@@ -68,16 +68,17 @@ public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfig
@Value("${sample.jwe-key-value}") @Value("${sample.jwe-key-value}")
RSAPrivateKey key; RSAPrivateKey key;
@Override @Bean
protected void configure(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off // @formatter:off
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeHttpRequests((authorize) -> authorize
.antMatchers("/message/**").hasAuthority("SCOPE_message:read") .antMatchers("/message/**").hasAuthority("SCOPE_message:read")
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.oauth2ResourceServer((oauth2) -> oauth2.jwt(withDefaults())); .oauth2ResourceServer((oauth2) -> oauth2.jwt(withDefaults()));
// @formatter:on // @formatter:on
return http.build();
} }
@Bean @Bean
@@ -22,7 +22,8 @@ plugins {
} }
repositories { repositories {
jcenter() mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@@ -38,4 +39,5 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

Some files were not shown because too many files have changed in this diff Show More