Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88f886e646 | |||
| cb4bd098e3 | |||
| bce2126fd1 | |||
| 545ffedea3 | |||
| 55e14fcb86 | |||
| 57c0b8a4c4 | |||
| 3dd832f99f | |||
| e995914653 | |||
| a4cef77512 | |||
| c5a2162b07 | |||
| f1c448becc | |||
| dec2e57170 | |||
| 070916cbcd | |||
| 15adedbf87 | |||
| 7058a3592c | |||
| 2a9a874d41 | |||
| 7d80162ab9 | |||
| f4afba567a | |||
| a6e0f60def | |||
| 75f86c51ec | |||
| fe037cf4d7 | |||
| b2ec34de55 | |||
| 91a69b36f9 | |||
| 7b653aab91 | |||
| a43cbcab41 | |||
| 6a60e655e3 | |||
| ca32d8e45d | |||
| 3a58daf55d | |||
| 3a4eec6eda | |||
| 5354f8b349 | |||
| 482dfc9a59 | |||
| 7426260ee1 | |||
| 313dbd7a18 | |||
| b48c07d36d | |||
| ca19311b20 | |||
| 7d915468ae | |||
| 6dc97460c8 | |||
| 5097f9dcfc | |||
| 76d4b1e5a3 | |||
| c4eaac0423 | |||
| 52cc331d9c | |||
| 6548ff0876 | |||
| bf1ca80a0a | |||
| aae31aee16 | |||
| cbd87c4e04 | |||
| f3348eec4a | |||
| c35ba7bf5d | |||
| 4ccd5ce84b | |||
| 1ad87dcaf5 | |||
| 67f36c5862 | |||
| def1af3e75 | |||
| cb5b762681 | |||
| f6439ddba8 | |||
| 15eaf5377b | |||
| c9ed471e8d | |||
| 2ad47fdc67 | |||
| 789a203355 | |||
| 10b517f7b6 | |||
| 2396aa4630 | |||
| 868fb455c8 | |||
| 601f54a4c1 |
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: '11'
|
||||
java-version: '17'
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
|
||||
@@ -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
|
||||
|
||||
Generated
+2
-2
@@ -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" />
|
||||
</project>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="temurin-17" project-jdk-type="JavaSDK" />
|
||||
</project>
|
||||
|
||||
+68
@@ -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]
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
version=5.5.1-SNAPSHOT
|
||||
spring-security.version=5.5.1-SNAPSHOT
|
||||
org.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError
|
||||
version=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.5.0'
|
||||
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.5.0'
|
||||
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-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
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.5.0'
|
||||
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.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.3-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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '2.6.4'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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
|
||||
|
||||
reactive/webflux/java/authentication/username-password/form/gradle/wrapper/gradle-wrapper.properties
Vendored
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+2
@@ -70,8 +70,10 @@ public class LoginPage {
|
||||
|
||||
private WebDriver driver;
|
||||
|
||||
@FindBy(id = "username")
|
||||
private WebElement username;
|
||||
|
||||
@FindBy(id = "password")
|
||||
private WebElement password;
|
||||
|
||||
@FindBy(css = "button[type=submit]")
|
||||
|
||||
+1
-1
@@ -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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+1
-1
@@ -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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+2
@@ -51,8 +51,10 @@ public class LoginPage {
|
||||
|
||||
private WebDriver webDriver;
|
||||
|
||||
@FindBy(id = "username")
|
||||
private WebElement username;
|
||||
|
||||
@FindBy(id = "password")
|
||||
private WebElement password;
|
||||
|
||||
@FindBy(css = "button[type=submit]")
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ public class SecurityConfiguration {
|
||||
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
|
||||
// @formatter:off
|
||||
http
|
||||
.authorizeExchange((exchanges) -> exchanges
|
||||
.authorizeExchange((authorize) -> authorize
|
||||
.anyExchange().authenticated()
|
||||
)
|
||||
.formLogin(withDefaults());
|
||||
|
||||
+1
-1
@@ -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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-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
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.5.0'
|
||||
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.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.3-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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.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.3-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.3-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
|
||||
|
||||
@@ -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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -14,7 +15,7 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-webflux'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testImplementation 'org.springframework.security:spring-security-test'
|
||||
@@ -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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+65
@@ -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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+3
-1
@@ -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(
|
||||
|
||||
+1
-1
@@ -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 'io.spring.dependency-management' version '1.0.10.RELEASE'
|
||||
id "nebula.integtest" version "7.0.9"
|
||||
id 'org.springframework.boot' version '3.0.0-M1'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -14,7 +15,7 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
|
||||
implementation 'org.springframework:spring-webflux'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
||||
implementation 'io.projectreactor.netty:reactor-netty'
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
@@ -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=6.0.0-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+1
-1
@@ -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()
|
||||
)
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureWebTestClient
|
||||
@AutoConfigureWebTestClient(timeout = "36000")
|
||||
public class OAuth2WebClientWebFluxApplicationTests {
|
||||
|
||||
@Autowired
|
||||
|
||||
+1
-1
@@ -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,10 +1,10 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
id("org.springframework.boot") version "2.5.0"
|
||||
id("io.spring.dependency-management") version "1.0.9.RELEASE"
|
||||
kotlin("jvm") version "1.5.0"
|
||||
kotlin("plugin.spring") version "1.5.0"
|
||||
id("org.springframework.boot") version "3.0.0-M1"
|
||||
id("io.spring.dependency-management") version "1.0.11.RELEASE"
|
||||
kotlin("jvm") version "1.6.0"
|
||||
kotlin("plugin.spring") version "1.6.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -12,13 +12,16 @@ repositories {
|
||||
maven {
|
||||
url = uri("https://repo.spring.io/snapshot")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://repo.spring.io/milestone")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
||||
implementation("org.springframework.boot:spring-boot-starter-webflux")
|
||||
implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5")
|
||||
implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6")
|
||||
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
@@ -34,10 +37,10 @@ dependencies {
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = listOf("-Xjsr305=strict")
|
||||
jvmTarget = "1.8"
|
||||
jvmTarget = "17"
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
spring-security.version=5.5.1-SNAPSHOT
|
||||
spring-security.version=6.0.0-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -4,10 +4,21 @@ plugins {
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url "https://repo.spring.io/milestone" }
|
||||
maven { url "https://repo.spring.io/snapshot" }
|
||||
}
|
||||
|
||||
compileJava {
|
||||
sourceCompatibility "1.8"
|
||||
targetCompatibility "1.8"
|
||||
}
|
||||
|
||||
compileTestJava {
|
||||
sourceCompatibility "1.8"
|
||||
targetCompatibility "1.8"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
aspect platform("org.springframework:spring-framework-bom:5.3.0")
|
||||
aspect platform("org.springframework.security:spring-security-bom:5.4.0-SNAPSHOT")
|
||||
@@ -19,7 +30,7 @@ dependencies {
|
||||
|
||||
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 +42,7 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -34,4 +35,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -34,4 +35,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
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 "4.0.0"
|
||||
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:6.0.0-SNAPSHOT")
|
||||
implementation platform("org.springframework.security:spring-security-bom:6.0.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.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE"
|
||||
implementation "org.thymeleaf:thymeleaf-spring6:3.1.0.M1"
|
||||
|
||||
testImplementation "org.assertj:assertj-core:3.18.0"
|
||||
testImplementation "org.springframework:spring-test"
|
||||
@@ -34,4 +35,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
gretty {
|
||||
servletContainer = "tomcat9"
|
||||
servletContainer = "tomcat10"
|
||||
contextPath = "/"
|
||||
fileLogEnabled = false
|
||||
integrationTestTask = 'integrationTest'
|
||||
@@ -38,4 +38,4 @@ project.tasks.matching { it.name == "integrationTest" }.all {
|
||||
integrationTest.systemProperty 'app.httpBaseURI', httpBaseUrl
|
||||
integrationTest.systemProperty 'app.httpsBaseURI', httpsBaseUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
package example;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import jakarta.servlet.Filter;
|
||||
|
||||
import org.springframework.web.filter.HiddenHttpMethodFilter;
|
||||
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
|
||||
|
||||
+4
-4
@@ -16,10 +16,10 @@
|
||||
|
||||
package example;
|
||||
|
||||
import org.thymeleaf.spring5.ISpringTemplateEngine;
|
||||
import org.thymeleaf.spring5.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
|
||||
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
|
||||
import org.thymeleaf.spring6.ISpringTemplateEngine;
|
||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
|
||||
import org.thymeleaf.spring6.view.ThymeleafViewResolver;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -34,4 +35,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -36,4 +37,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -37,4 +38,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -32,4 +33,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+2
-8
@@ -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();
|
||||
|
||||
+11
-11
@@ -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
|
||||
|
||||
Executable → Regular
@@ -1,28 +1,28 @@
|
||||
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.data:spring-data-releasetrain:Neumann-SR5")
|
||||
implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
|
||||
implementation platform("org.springframework:spring-framework-bom:6.0.0-SNAPSHOT")
|
||||
implementation platform("org.springframework.security:spring-security-bom:6.0.0-SNAPSHOT")
|
||||
implementation platform("org.junit:junit-bom:5.7.0")
|
||||
|
||||
implementation "org.springframework.security:spring-security-config"
|
||||
implementation "org.springframework.security:spring-security-data"
|
||||
implementation "org.springframework.security:spring-security-web"
|
||||
implementation 'jakarta.validation:jakarta.validation-api:2.0.2'
|
||||
implementation 'javax.persistence:javax.persistence-api:2.2'
|
||||
implementation 'org.hibernate:hibernate-entitymanager:5.4.22.Final'
|
||||
implementation 'org.hibernate.validator:hibernate-validator:6.1.6.Final'
|
||||
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
|
||||
implementation 'org.hibernate.orm:hibernate-core:6.0.0.Beta2'
|
||||
implementation 'org.hibernate.validator:hibernate-validator:7.0.1.Final'
|
||||
implementation 'org.hsqldb:hsqldb:2.5.1'
|
||||
implementation 'org.springframework.data:spring-data-jpa'
|
||||
implementation 'org.springframework.data:spring-data-jpa:3.0.0-SNAPSHOT'
|
||||
|
||||
testImplementation "org.assertj:assertj-core:3.18.0"
|
||||
testImplementation "org.springframework:spring-test"
|
||||
@@ -34,4 +34,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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -18,12 +18,12 @@ package example;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
||||
@Entity
|
||||
public class Message {
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package example;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
/**
|
||||
* A user.
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
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 "4.0.0"
|
||||
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:6.0.0-SNAPSHOT")
|
||||
implementation platform("org.springframework.security:spring-security-bom:6.0.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.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE"
|
||||
implementation "org.thymeleaf:thymeleaf-spring6:3.1.0.M1"
|
||||
|
||||
testImplementation "org.assertj:assertj-core:3.18.0"
|
||||
testImplementation "org.springframework:spring-test"
|
||||
@@ -34,4 +35,5 @@ dependencies {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
gretty {
|
||||
servletContainer = "tomcat9"
|
||||
servletContainer = "tomcat10"
|
||||
contextPath = "/"
|
||||
fileLogEnabled = false
|
||||
integrationTestTask = 'integrationTest'
|
||||
@@ -38,4 +38,4 @@ project.tasks.matching { it.name == "integrationTest" }.all {
|
||||
integrationTest.systemProperty 'app.httpBaseURI', httpBaseUrl
|
||||
integrationTest.systemProperty 'app.httpsBaseURI', httpsBaseUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user