56 Commits

Author SHA1 Message Date
Marcus Da Coregio 32c8db1c3e Add Gradle Enterprise plugin
Issue gh-94
2022-09-16 08:55:29 -03:00
Marcus Da Coregio d7a34c849a Accept gradle Terms of Service
Issue gh-94
2022-09-16 08:55:29 -03:00
Marcus Da Coregio 67d1bb921d Add new task that runs all subproject's tests 2022-09-16 08:55:29 -03:00
Marcus Da Coregio 1fc20d346e Fix command to run Spring Boot SAML2 samples 2022-07-28 16:17:46 -03:00
Rob Winch b2310d91fe jcenter() -> mavenCentral()
jcenter is intermittently producing circular redirects. It is deprecated and we should use
Maven Central anyway.
2022-05-18 10:39:49 -05: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
Josh Cummings ca32d8e45d Update authorizeHttpRequests
Closes gh-49
2021-11-10 10:20:09 -07:00
Josh Cummings 3a58daf55d Update HttpSecurity Formatting 2021-11-10 09:42:09 -07:00
Marcus Da Coregio 3a4eec6eda Add SAML 2.0 Metadata Refresh Sample
Closes gh-2
2021-11-02 20:31:15 -03:00
Marcus Da Coregio 5354f8b349 Add saml2-login java-configuration tests
Closes gh-10
2021-11-02 13:26:19 -03:00
Marcus Da Coregio 482dfc9a59 Fix formatting 2021-10-29 14:42:11 -03:00
Josh Cummings 7426260ee1 Add Second Tenant to SAML 2.0 Login 2021-10-28 17:25:54 -06:00
Marcus Da Coregio 313dbd7a18 Add saml2-login java-configuration sample
Issue gh-10
2021-10-21 11:56:31 -03:00
Josh Cummings b48c07d36d Add SAML 2.0 Single Tenant Sample 2021-10-12 08:52:10 -06:00
Josh Cummings ca19311b20 Add Metadata Endpoint 2021-10-12 08:48:20 -06:00
Josh Cummings 7d915468ae Move Saml2 Login Sample
To make room for more SAML 2.0 samples!
2021-10-12 08:40:44 -06:00
Marcus Da Coregio 6dc97460c8 Disable X.509 integration tests
When moving to gretty newer version there is a conflict in tomcat configuration.
This tests should be re-enabled

Issue gh-45
2021-10-04 15:06:08 -03:00
Marcus Da Coregio 5097f9dcfc Update to Gradle 7.2
Closes gh-45
2021-10-04 15:04:13 -03:00
Josh Cummings 76d4b1e5a3 Fix Formatting
Issue gh-44
2021-09-27 16:57:16 -06:00
Josh Cummings c4eaac0423 Update to Use JwtEncoder
Closes gh-44
2021-09-27 16:43:29 -06:00
Steve Riesenberg 52cc331d9c Update oauth login samples
Closes gh-29
2021-09-23 15:06:45 -05:00
Steve Riesenberg 6548ff0876 Update resource server samples
Closes gh-28
2021-09-23 15:06:45 -05:00
Marcus Da Coregio bf1ca80a0a Update README 2021-09-23 15:08:46 -03:00
Steve Riesenberg aae31aee16 Update to Spring Authorization Server 0.2.0
Closes gh-39
2021-09-21 11:39:20 -05:00
Josh Cummings cbd87c4e04 Update SAML 2.0 Login sample to use SAML 2.0 Logout
Closes gh-36
2021-09-14 10:32:44 -03:00
Marcus Da Coregio f3348eec4a Add ACL Document Management System XML sample
Closes gh-34
2021-09-06 09:40:35 -03:00
Marcus Da Coregio c35ba7bf5d Add ACL Contacts XML sample
Closes gh-32
2021-09-06 09:18:49 -03:00
Josh Cummings 4ccd5ce84b Use Spring Boot properties
Closes gh-30
2021-09-03 16:36:06 -06:00
Josh Cummings 1ad87dcaf5 Update to Spring Boot 2.5.2 2021-07-28 15:39:06 -06:00
Steve Riesenberg 67f36c5862 Add authorization server sample 2021-07-26 23:09:25 -05:00
Marcus Da Coregio def1af3e75 Add PreAuth Xml sample project
Closes gh-26
2021-07-23 14:15:37 -03:00
Marcus Da Coregio cb5b762681 Add gradlew files
Issue gh-25
2021-07-23 13:33:47 -03:00
Marcus Da Coregio f6439ddba8 Add Hello Spring Security Xml Config project
Closes gh-25
2021-07-23 11:54:37 -03:00
Marcus Da Coregio 15eaf5377b Add IDEA file to git exclusion 2021-07-23 09:35:54 -03:00
Josh Cummings c9ed471e8d Add LDAP Sample 2021-06-15 16:56:59 -06:00
Josh Cummings 2ad47fdc67 Use JDK 11
Closes gh-21
2021-05-27 10:40:51 -06:00
Josh Cummings 789a203355 Use OpenSAML 4 in SAML 2.0 Login Sample
Closes gh-20
2021-05-27 10:27:20 -06:00
Josh Cummings 10b517f7b6 Update Kotlin Samples
Closes gh-19
2021-05-27 10:17:25 -06:00
Josh Cummings 2396aa4630 Mfa Sample Depends on spring-security-crypto
Closes gh-18
2021-05-27 09:34:31 -06:00
Josh Cummings 868fb455c8 Update to Spring Security 5.6.0-SNAPSHOT 2021-05-27 09:31:47 -06:00
Josh Cummings 601f54a4c1 Sync Gradle Version
Issue gh-16
2021-05-27 09:14:29 -06:00
299 changed files with 13707 additions and 740 deletions
+1
View File
@@ -73,6 +73,7 @@ local.properties
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/libraries-with-intellij-classes.xml
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
+1 -1
View File
@@ -4,5 +4,5 @@
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</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>
+68
View File
@@ -1,3 +1,71 @@
image::https://github.com/spring-projects/spring-security-samples/workflows/CI/badge.svg[link=https://github.com/spring-projects/spring-security-samples/actions?query=workflow%3ACI]
Samples for https://github.com/spring-projects/spring-security
== Samples catalog
=== Getting Started
* Hello Security - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/hello-security[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/hello-security[WebFlux] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux-fn/hello-security[WebFlux.fn] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/hello-security[Java Configuration] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/xml/java/helloworld[XML] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/kotlin/hello-security[Kotlin] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/kotlin/hello-security[WebFlux Kotlin] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/rsocket/hello-security[RSocket]
* Hello Security (without Spring MVC) - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/hello-security-explicit[Java Configuration]
* Hello Security with Explicit Configuration - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/hello-security-explicit[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/hello-security-explicit[WebFlux] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/hello-mvc-security[Java Configuration]
* Method Security - https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/method[WebFlux]
* Spring Data Integration - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/data[Java Configuration]
* Max Sessions - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/max-sessions[Java Configuration]
* AspectJ Security Configuration - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/aspectj[Java Configuration]
=== OAuth 2.0
* https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/authorization-server[Authorization Server]
* Login - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/login[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/oauth2/login[WebFlux]
* Resource Server
** Hello Security - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/hello-security[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/oauth2/resource-server[WebFlux]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/jwe[JSON Web Encryption (JWE)]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/multi-tenancy[Multi-tenancy]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/opaque[Opaque Token]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/static[Static]
* WebClient - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/webclient[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/oauth2/webclient[WebFlux]
=== SAML 2.0
* Login & Logout - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/saml2/login[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/saml2/login[Java Configuration]
=== Authentication
* https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/preauth[Pre-authentication]
* https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/remember-me[Remember-me]
* Username and password
** Form Login - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/form[Java Configuration] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/authentication/username-password/form[WebFlux]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/in-memory[In-memory `UserDetailsService`]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/jdbc[JDBC]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/ldap[LDAP]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/authentication/username-password/mfa[Multi-factor authentication]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/authentication/username-password/user-details-service/custom-user[Custom `UserDetails`]
* X.509 - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/x509[Java Configuration] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/authentication/x509[WebFlux]
=== JWT
* Login - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/jwt/login[Spring Boot]
+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.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
org.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+5 -3
View File
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class HelloTests {
@Autowired
+5 -3
View File
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -19,4 +20,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
+2 -2
View File
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class HelloTests {
@Autowired
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -25,4 +26,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -53,7 +53,7 @@ public class WebfluxFormSecurityConfiguration {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange((exchanges) -> exchanges
.authorizeExchange((authorize) -> authorize
.pathMatchers("/login").permitAll()
.anyExchange().authenticated()
)
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -53,7 +53,7 @@ public class WebfluxX509Application {
// @formatter:off
http
.x509(withDefaults())
.authorizeExchange((exchanges) -> exchanges
.authorizeExchange((authorize) -> authorize
.anyExchange().authenticated()
);
// @formatter:on
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -23,4 +24,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -39,7 +39,7 @@ public class SecurityConfiguration {
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange((exchanges) -> exchanges
.authorizeExchange((authorize) -> authorize
.anyExchange().authenticated()
)
.formLogin(withDefaults());
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class HelloSecurityTests {
@Autowired
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class HelloSecurityTests {
@Autowired
+5 -3
View File
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -19,4 +20,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class HelloTests {
@Autowired
+5 -3
View File
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -45,7 +45,7 @@ public class SecurityConfiguration {
http
// Demonstrate that method security works
// Best practice to use both for defense in depth
.authorizeExchange((exchanges) -> exchanges
.authorizeExchange((authorize) -> authorize
.anyExchange().permitAll()
)
.httpBasic(withDefaults());
@@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class HelloMethodApplicationTests {
@Autowired
+99 -12
View File
@@ -1,18 +1,105 @@
NOTE: Spring Security Reactive OAuth only supports authentication using a user info endpoint.
Support for JWT validation will be added in https://github.com/spring-projects/spring-security/issues/5330[gh-5330].
= OAuth 2.0 Login Sample
This guide provides instructions on setting up the sample application with OAuth 2.0 Login using an OAuth 2.0 Provider or OpenID Connect 1.0 Provider.
The sample application uses Spring Boot 2.0.0.M6 and the `spring-security-oauth2-client` module which is new in Spring Security 5.0.
The sample application uses Spring Boot 2.5 and the `spring-security-oauth2-client` module which is new in Spring Security 5.0.
The following sections provide detailed steps for setting up OAuth 2.0 Login for these Providers:
* <<spring-login, Spring Authorization Server>>
* <<google-login, Google>>
* <<github-login, GitHub>>
* <<facebook-login, Facebook>>
* <<okta-login, Okta>>
[[spring-login]]
== Login with Spring Authorization Server
This section shows how to configure the sample application using Spring Authorization Server as the Authentication Provider and covers the following topics:
* <<spring-initial-setup,Initial setup>>
* <<spring-redirect-uri,Setting the redirect URI>>
* <<spring-application-config,Configure application.yml>>
* <<spring-boot-application,Boot up the application>>
[[spring-initial-setup]]
=== Initial setup
The sample application is pre-configured to work out of the box with Spring Authorization Server, which runs locally on port `9000`. See the https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/authorization-server[authorization-server sample] to run the authorization server used in this section.
NOTE: https://github.com/spring-projects-external/spring-authorization-server[Spring Authorization Server] supports the https://openid.net/connect/[OpenID Connect 1.0] specification.
[[spring-redirect-uri]]
=== Setting the redirect URI
The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Spring Authorization Server
and have granted access to the OAuth Client on the Consent page.
The default redirect URI is `http://127.0.0.1:8080/login/oauth2/code/login-client`. No special setup is required to use the sample locally.
TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
The *_registrationId_* is a unique identifier for the `ClientRegistration`.
IMPORTANT: If the application is running behind a proxy server, it is recommended to check https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#appendix-proxy-server[Proxy Server Configuration] to ensure the application is correctly configured.
Also, see the supported https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#oauth2Client-auth-code-redirect-uri[`URI` template variables] for `redirect-uri`.
[[spring-application-config]]
=== Configure application.yml
If you wish to customize the OAuth Client to work with a non-local deployment of Spring Authorization Server, you need to configure the application to use the OAuth Client for the _authentication flow_. To do so:
. Go to `application.yml` and set the following configuration:
+
[source,yaml]
----
spring:
security:
oauth2:
client:
registration: <1>
login-client: <2>
provider: spring <3>
client-id: login-client
client-secret: openid-connect
client-authentication-method: client_secret_basic
authorization-grant-type: authorization_code
redirect-uri: http://127.0.0.1:8080/login/oauth2/code/login-client
scope: openid,profile <4>
client-name: Spring
provider:<5>
spring:
authorization-uri: http://localhost:9000/oauth2/authorize
token-uri: http://localhost:9000/oauth2/token
jwk-set-uri: http://localhost:9000/oauth2/jwks
issuer-uri: http://localhost:9000
----
+
.OAuth Client properties
====
<1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties.
<2> Following the base property prefix is the ID for the `ClientRegistration`, such as login-client.
<3> The `provider` property specifies which provider configuration is used by this `ClientRegistration`.
<4> The `openid` scope is required by Spring Authorization Server to perform https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[authentication using OpenID Connect 1.0].
<5> `spring.security.oauth2.client.provider` is the base property prefix for OAuth Provider properties.
====
. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials for your Spring Authorization Server. As well, replace `http://localhost:9000` in `authorization-uri`, `token-uri` and `jwk-set-uri` with the actual domain of your authorization server.
[[spring-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Spring.
Click on the Spring link, and you are then redirected to the Spring Authorization Server for authentication.
After authenticating with your credentials (`user` and `password` by default), the next page presented to you is the Consent screen.
The Consent screen asks you to either allow or deny access to the OAuth Client. Select "profile" and
click *Submit Consent* to authorize the OAuth Client to access your basic profile information.
At this point, the OAuth Client retrieves your basic profile information via the https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken[ID Token] and establishes an authenticated session.
NOTE: Spring Authorization Server does not currently support the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint], which is optional in OpenID Connect 1.0. See https://github.com/spring-projects-experimental/spring-authorization-server/issues/176[#176] fo more information.
[[google-login]]
== Login with Google
@@ -41,7 +128,7 @@ After completing the "Obtain OAuth 2.0 credentials" instructions, you should hav
The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Google
and have granted access to the OAuth Client _(created in the previous step)_ on the Consent page.
In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`.
In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://127.0.0.1:8080/login/oauth2/code/google`.
TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
The *_registrationId_* is a unique identifier for the `ClientRegistration`.
@@ -79,7 +166,7 @@ spring:
[[google-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Google.
Click on the Google link, and you are then redirected to Google for authentication.
@@ -105,7 +192,7 @@ This section shows how to configure the sample application using GitHub as the A
To use GitHub's OAuth 2.0 authentication system for login, you must https://github.com/settings/applications/new[Register a new OAuth application].
When registering the OAuth application, ensure the *Authorization callback URL* is set to `http://localhost:8080/login/oauth2/code/github`.
When registering the OAuth application, ensure the *Authorization callback URL* is set to `http://127.0.0.1:8080/login/oauth2/code/github`.
The Authorization callback URL (redirect URI) is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with GitHub
and have granted access to the OAuth application on the _Authorize application_ page.
@@ -146,7 +233,7 @@ spring:
[[github-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for GitHub.
Click on the GitHub link, and you are then redirected to GitHub for authentication.
@@ -183,7 +270,7 @@ NOTE: The selection for the _Category_ field is not relevant but it's a required
The next page presented is "Product Setup". Click the "Get Started" button for the *Facebook Login* product.
In the left sidebar, under _Products -> Facebook Login_, select _Settings_.
For the field *Valid OAuth redirect URIs*, enter `http://localhost:8080/login/oauth2/code/facebook` then click _Save Changes_.
For the field *Valid OAuth redirect URIs*, enter `http://127.0.0.1:8080/login/oauth2/code/facebook` then click _Save Changes_.
The OAuth redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Facebook
and have granted access to the application on the _Authorize application_ page.
@@ -224,7 +311,7 @@ spring:
[[facebook-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Facebook.
Click on the Facebook link, and you are then redirected to Facebook for authentication.
@@ -259,7 +346,7 @@ From the "Add Application" page, select the "Create New App" button and enter th
Select the _Create_ button.
On the "General Settings" page, enter the Application Name (for example, "Spring Security Okta Login") and then select the _Next_ button.
On the "Configure OpenID Connect" page, enter `http://localhost:8080/login/oauth2/code/okta` for the field *Redirect URIs* and then select _Finish_.
On the "Configure OpenID Connect" page, enter `http://127.0.0.1:8080/login/oauth2/code/okta` for the field *Redirect URIs* and then select _Finish_.
The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Okta
and have granted access to the application on the _Authorize application_ page.
@@ -315,7 +402,7 @@ As well, replace `https://your-subdomain.oktapreview.com` in `authorization-uri`
[[okta-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Okta.
Click on the Okta link, and you are then redirected to Okta for authentication.
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -24,4 +25,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -36,7 +36,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
* @author Rob Winch
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class OAuth2LoginApplicationTests {
@Autowired
@@ -0,0 +1,65 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import reactor.core.publisher.Mono;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
/**
* This filter ensures that the loopback IP <code>127.0.0.1</code> is used to access the
* application so that the sample works correctly, due to the fact that redirect URIs with
* "localhost" are rejected by the Spring Authorization Server, because the OAuth 2.1
* draft specification states:
*
* <pre>
* While redirect URIs using localhost (i.e.,
* "http://localhost:{port}/{path}") function similarly to loopback IP
* redirects described in Section 10.3.3, the use of "localhost" is NOT
* RECOMMENDED.
* </pre>
*
* @author Steve Riesenberg
* @see <a href=
* "https://tools.ietf.org/html/draft-ietf-oauth-v2-1-01#section-9.7.1">Loopback Redirect
* Considerations in Native Apps</a>
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class LoopbackIpRedirectWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String host = exchange.getRequest().getURI().getHost();
if (host != null && host.equals("localhost")) {
UriComponents uri = UriComponentsBuilder.fromHttpRequest(exchange.getRequest()).host("127.0.0.1").build();
exchange.getResponse().setStatusCode(HttpStatus.PERMANENT_REDIRECT);
exchange.getResponse().getHeaders().setLocation(uri.toUri());
return Mono.empty();
}
return chain.filter(exchange);
}
}
@@ -15,6 +15,15 @@ spring:
oauth2:
client:
registration:
login-client:
provider: spring
client-id: login-client
client-secret: openid-connect
client-authentication-method: client_secret_basic
authorization-grant-type: authorization_code
redirect-uri: http://127.0.0.1:8080/login/oauth2/code/login-client
scope: openid,profile
client-name: Spring
google:
client-id: your-app-client-id
client-secret: your-app-client-secret
@@ -28,6 +37,10 @@ spring:
client-id: your-app-client-id
client-secret: your-app-client-secret
provider:
spring:
authorization-uri: http://localhost:9000/oauth2/authorize
token-uri: http://localhost:9000/oauth2/token
jwk-set-uri: http://localhost:9000/oauth2/jwks
okta:
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
@@ -1,7 +1,7 @@
= OAuth 2.0 Resource Server Sample
This sample demonstrates integrating Resource Server with a mock Authorization Server, though it can be modified to integrate
with your favorite Authorization Server.
This sample demonstrates integrating Resource Server with the Spring Authorization Server, though it can be modified to integrate
with a mock server or your favorite Authorization Server.
With it, you can run the integration tests or run the application as a stand-alone service to explore how you can
secure your own service with OAuth 2.0 Bearer Tokens using Spring Security.
@@ -18,7 +18,7 @@ Or import the project into your IDE and run `ServerOAuth2ResourceServerApplicati
=== What is it doing?
By default, the tests are pointing at a mock Authorization Server instance.
By default, the tests are pointing at a mock Authorization Server instance via the `test` profile.
The tests are configured with a set of hard-coded tokens originally obtained from the mock Authorization Server,
and each makes a query to the Resource Server with their corresponding token.
@@ -31,7 +31,17 @@ Hello, subject!
where "subject" is the value of the `sub` field in the JWT returned by the Authorization Server.
== 2. Running the app
== 2. Running the app with Spring Authorization Server
Before running this application with the default configuration, you will need to start up an Authorization Server, such as the https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/authorization-server[authorization-server sample] in this project which is pre-configured to work with this Resource Server sample out of the box.
To run the Authorization Server as a stand-alone application, navigate to the `servlet/spring-boot/java/oauth2/authorization-server` and do:
```bash
./gradlew bootRun
```
Or import the project into your IDE and run `OAuth2AuthorizationServerApplication` from there. Next, you can run this Resource Server.
To run as a stand-alone application, do:
@@ -41,6 +51,89 @@ To run as a stand-alone application, do:
Or import the project into your IDE and run `ServerOAuth2ResourceServerApplication` from there.
Once it is up and running, you can issue the following request:
```bash
curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:read"
```
This returns something like the following:
```json
{
"access_token": "eyJraWQiOiI4YWY4Zjc2Zi0zMTdkLTQxZmYtYWY5Yi1hZjg5NDg4ODM5YzciLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtZXNzYWdpbmctY2xpZW50IiwiYXVkIjoibWVzc2FnaW5nLWNsaWVudCIsIm5iZiI6MTYyNzMzNDQ1MCwic2NvcGUiOlsibWVzc2FnZTpyZWFkIl0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo5MDAwIiwiZXhwIjoxNjI3MzM0NzUwLCJpYXQiOjE2MjczMzQ0NTAsImp0aSI6IjBiYjYwZjhkLWIzNjItNDk0MC05MGRmLWZhZDg4N2Q1Yzg1ZSJ9.O8dI67B_feRjOn6pJi5ctPJmUJCNpV77SC4OiWqmpa5UHvf4Ud6L6EFe9LKuPIRrEWi8rMdCdMBOPKQMXvxLoI3LMUPf7Yj973uvZN0E988MsKwhGwxyaa_Wam8wFlk8aQlN8SbW3cKdeH-nKloNMdwjfspovefX521mxouaMjmyXdIFrM5WZ15GZK69NIniACSatE-pc9TAjKYBDbC65jVt_zHEvDQbEkZulF2bjrGOZC8C3IbJWnlKgkcshrY44TtrGPyCp2gIS0TSUUsG00iSBBC8E8zPU-YdfaP8gB9_FwUwK9zfy_hU2Ykf2aU3eulpGDVLn2rCwFeK86Rw1w",
"expires_in": 299,
"scope": "message:read",
"token_type": "Bearer"
}
```
Then, export the access token from the response:
```bash
export TOKEN=...
```
Then issue the following request:
```bash
curl -H "Authorization: Bearer $TOKEN" localhost:8080
```
Which will respond with the phrase:
```
Hello, messaging-client!
```
where `messaging-client` is the value of the `sub` field in the JWT returned by the Authorization Server.
Or this to make a GET request to /message:
```bash
curl -H "Authorization: Bearer $TOKEN" localhost:8080/message
```
Will respond with:
```bash
secret message
```
In order to make a POST request to /message, you can use the following request:
```bash
curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:write"
```
Then, export the access token from the response:
```bash
export TOKEN=...
```
Then issue the following request:
```bash
curl -H "Authorization: Bearer $TOKEN" -d "my message" localhost:8080/message
```
Which will respond with:
```bash
Message was created. Content: my message
```
== 3. Running the app with a mock Authorization Server
To run as a stand-alone application with an embedded mock Authorization Server, do:
```bash
./gradlew bootRun --args='--spring.profiles.active=test'
```
Or import the project into your IDE and run `ServerOAuth2ResourceServerApplication` from there with the `test` profile active.
Once it is up, you can use the following token:
```bash
@@ -75,7 +168,7 @@ Will respond with:
secret message
```
== 2. Testing against other Authorization Servers
== 4. Testing against other Authorization Servers
_In order to use this sample, your Authorization Server must support JWTs that either use the "scope" or "scp" attribute._
@@ -87,7 +180,7 @@ spring:
oauth2:
resourceserver:
jwt:
jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json
jwk-set-uri: http://localhost:9000/oauth2/jwks
```
And change the property to your Authorization Server's JWK set endpoint:
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -21,4 +22,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.hamcrest.Matchers.containsString;
@@ -35,7 +36,8 @@ import static org.hamcrest.Matchers.containsString;
* @since 5.1
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
@ActiveProfiles("test")
public class ServerOAuth2ResourceServerApplicationITests {
Consumer<HttpHeaders> noScopesToken = (http) -> http.setBearerAuth(
@@ -37,7 +37,7 @@ public class SecurityConfiguration {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange((exchanges) -> exchanges
.authorizeExchange((authorize) -> authorize
.pathMatchers(HttpMethod.GET, "/message/**").hasAuthority("SCOPE_message:read")
.pathMatchers(HttpMethod.POST, "/message/**").hasAuthority("SCOPE_message:write")
.anyExchange().authenticated()
@@ -0,0 +1,6 @@
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json
@@ -3,4 +3,4 @@ spring:
oauth2:
resourceserver:
jwt:
jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json
jwk-set-uri: http://localhost:9000/oauth2/jwks
@@ -1,12 +1,13 @@
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
id 'java'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
@@ -24,4 +25,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,2 +1,2 @@
version=5.5.1-SNAPSHOT
spring-security.version=5.5.1-SNAPSHOT
version=5.7.0-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -37,7 +37,7 @@ public class SecurityConfiguration {
SecurityWebFilterChain configure(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange((exchanges) -> exchanges
.authorizeExchange((authorize) -> authorize
.pathMatchers("/", "/public/**").permitAll()
.anyExchange().authenticated()
)
@@ -39,7 +39,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
@WebFluxTest
@Import({ SecurityConfiguration.class, OAuth2WebClientController.class })
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class OAuth2WebClientControllerTests {
private static MockWebServer web = new MockWebServer();
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @author Rob Winch
*/
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class OAuth2WebClientWebFluxApplicationTests {
@Autowired
@@ -39,7 +39,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
@WebFluxTest
@Import({ SecurityConfiguration.class, RegisteredOAuth2AuthorizedClientController.class })
@AutoConfigureWebTestClient
@AutoConfigureWebTestClient(timeout = "36000")
public class RegisteredOAuth2AuthorizedClientControllerTests {
private static MockWebServer web = new MockWebServer();
@@ -1 +1 @@
spring-security.version=5.5.1-SNAPSHOT
spring-security.version=5.7.0-SNAPSHOT
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -4,22 +4,23 @@ plugins {
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
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 "org.springframework.security:spring-security-aspects"
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
runtime "org.springframework.security:spring-security-aspects"
runtimeOnly "org.springframework.security:spring-security-aspects"
testImplementation "org.assertj:assertj-core:3.18.0"
testImplementation "org.springframework:spring-test"
@@ -31,6 +32,7 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.hsqldb:hsqldb:2.5.1"
@@ -36,4 +37,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -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");
* 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.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.authentication.BindAuthenticator;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.authentication.LdapAuthenticator;
import org.springframework.security.ldap.server.UnboundIdContainer;
import org.springframework.security.config.ldap.EmbeddedLdapServerContextSourceFactoryBean;
import org.springframework.security.config.ldap.LdapBindAuthenticationManagerFactory;
import org.springframework.security.ldap.userdetails.PersonContextMapper;
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
UnboundIdContainer ldapContainer() {
UnboundIdContainer result = new UnboundIdContainer("dc=springframework,dc=org", "classpath:users.ldif");
result.setPort(0);
return result;
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean = EmbeddedLdapServerContextSourceFactoryBean
.fromEmbeddedLdapServer();
contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
}
@Bean
DefaultSpringSecurityContextSource contextSource(UnboundIdContainer container) {
return new DefaultSpringSecurityContextSource(
"ldap://localhost:" + container.getPort() + "/dc=springframework,dc=org");
}
@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);
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
factory.setUserDnPatterns("uid={0},ou=people");
factory.setUserDetailsContextMapper(new PersonContextMapper());
return factory.createAuthenticationManager();
}
}
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
//apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -32,4 +33,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -24,7 +24,7 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;
@@ -41,15 +41,9 @@ import static org.assertj.core.api.Assertions.assertThatCode;
*
* @author Michael Simons
*/
@Disabled
public class X509Tests {
private int port;
@BeforeEach
void setup() {
this.port = Integer.parseInt(System.getProperty("app.httpPort", "8443"));
}
@Test
void notCertificateThenSslHandshakeException() {
RestTemplate rest = new RestTemplate();
@@ -18,28 +18,28 @@ package example;
import org.springframework.context.annotation.Bean;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
public class SecurityConfiguration {
@Override
// @formatter:off
protected void configure(HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests((authorizeRequests) ->
authorizeRequests
.anyRequest().authenticated()
)
.x509(withDefaults());
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.x509(withDefaults());
// @formatter:on
return http.build();
}
// @formatter:on
// @formatter:off
@Bean
+6 -4
View File
@@ -1,17 +1,18 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "nebula.integtest" version "8.2.0"
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
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.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -37,4 +38,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -1,20 +1,21 @@
plugins {
id "java"
id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.3"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
}
dependencies {
implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.springframework:spring-framework-bom:5.3.13")
implementation platform("org.springframework.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
@@ -34,4 +35,5 @@ dependencies {
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -0,0 +1,51 @@
= SAML 2.0 Login & Logout Sample
This guide provides instructions on setting up this SAML 2.0 Login & Logout sample application.
It uses https://simplesamlphp.org/[SimpleSAMLphp] as its asserting party.
The sample application uses Spring Boot and the `spring-security-saml2-service-provider`
module which is new in Spring Security 5.2.
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
=== 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 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:
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
3. Provide a framework for components used in SAML 2.0 authentication that can be swapped by configuration
4. Work against the Okta SAML 2.0 IDP reference implementation
=== 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 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.
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
=== Start up the Sample Boot Application
```
./gradlew :spring-security-samples-boot-saml2login:bootRun
```
=== Open a Browser
http://localhost:8080/
You will be redirect to the Okta SAML 2.0 IDP
=== Type in your credentials
```
User: testuser@spring.security.saml
Password: 12345678
```
@@ -0,0 +1,68 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
id "java"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "3.0.6"
id "war"
}
apply from: "gradle/gretty.gradle"
repositories {
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}
dependencies {
constraints {
implementation "org.opensaml:opensaml-core:4.1.1"
implementation "org.opensaml:opensaml-saml-api: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.security:spring-security-bom:5.7.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config"
implementation "org.springframework.security:spring-security-web"
implementation "org.springframework:spring-webmvc"
implementation "org.springframework.security:spring-security-saml2-service-provider"
implementation "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.2"
implementation "org.apache.taglibs:taglibs-standard-jstlel:1.2.5"
implementation "org.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE"
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE"
providedCompile "javax.servlet:javax.servlet-api:4.0.1"
providedCompile "javax.servlet.jsp:javax.servlet.jsp-api:2.3.3"
testImplementation "org.assertj:assertj-core:3.18.0"
testImplementation "org.springframework:spring-test"
testImplementation "org.springframework.security:spring-security-test"
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation "org.seleniumhq.selenium:htmlunit-driver:2.44.0"
testImplementation 'org.hamcrest:hamcrest:2.2'
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}
tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}

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