diff --git a/README.MD b/README.MD
index 5a4d4ea5e..e6c07f3fd 100644
--- a/README.MD
+++ b/README.MD
@@ -2,7 +2,7 @@ Do not hesitate to fork this repo and send pull requests, even for things as sma
# Spring-addons
The libraries hosted in this repo shine in two domains:
-- provide with annotations to mock OAuth2 `Authentication` during tests (`@WithMockJwtAuth`, `@WithOAuth2Login`, `@WithOidcLogin`, `@WithMockBearerTokenAuthentication`, etc.), which allow to test method security on any `@Component`. Details below.
+- provide with annotations to mock OAuth2 `Authentication` during tests (`@WithMockJwtAuth`, `@WithOAuth2Login`, `@WithOidcLogin`, `@WithMockBearerTokenAuthentication`, etc.), which allow to test method security on any `@Component`. **New in 6.1.12: `@JwtAuthenticationSource` and alike to work with JUnit 5 `@ParameterizedTest`**. Details below.
- help configuring Spring Boot 3 applications OAuth2 configuration by pushing auto-configuration to the next level. As shown in **[Tutorials](https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials)**, with 0 Java conf (just properties), we can configure:
* authorities mapping (source claims, prefix and case transformation), without having to provide authentication converter, user service or `GrantedAuthoritiesMapper` in each app
* fine grained CORS configuration (per path matcher), which enables to override allowed origins as environment variable when switching from `localhost` to `dev` or `prod` environments
@@ -29,6 +29,8 @@ To test method security on any type of `@Component` (`@Controller`, off course,
An [article covering the usage of OAuth2 test annotations from this lib](https://www.baeldung.com/spring-oauth-testing-access-control) was published on Baeldung. This, along with all [samples](https://github.com/ch4mpy/spring-addons/tree/master/samples) and [tutorials](https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials) source-code (which contain a lot of unit and integration testing), should be enough to get you started.
+Starting from `6.1.12`, `@JwtAuthenticationSource`, `@BearerAuthenticationSource`, `@OpenIdAuthenticationSource`, `@OAuth2LoginAuthenticationSource` and `@OidcLoginAuthenticationSource` were added to run the same JUnit 5 `@ParameterizedTest` with different `Authentication` instance. This can prove pretty handy to assert that access is actually granted for each of the entries in a `asAnyAuthority(...)` or `asAnyRole(...)` expression. See [Release Notes](#release-notes) or Javadoc for usage.
+
## 2. Spring Boot Starters
This repo contains thin wrappers around `spring-boot-starter-oauth2-resource-server` or `spring-boot-starter-oauth2-client`:
- [spring-addons-webflux-client](https://github.com/ch4mpy/spring-addons/tree/master/webflux/spring-addons-webflux-client) to be used in reactive applications rendering templates on the server (Thymeleaf, JSF, etc.), **or in `spring-cloud-gateway` used as BFF** (server-side OAuth2 confidential client securing a browser application with sessions and replacing session cookies with OAuth2 access tokens before forwarding requests from browsers to resource servers)
@@ -63,7 +65,7 @@ If locked wtih a lower JDK or spring-boot version, you'll have to use a 5.4.x re
I could forget to update README before releasing, so please refer to [maven central](https://repo1.maven.org/maven2/com/c4-soft/springaddons/spring-addons/) to pick latest available release
```xml
- 6.1.11
+ 6.1.12
webmvc
jwt
@@ -118,11 +120,11 @@ Using such libs is dead simple: just declare depedency on one of those libs and
2.0 comes with a noticeable amount of breaking changes. So lets start tracking features.
### 6.1.12
-- [gh-122](https://github.com/ch4mpy/spring-addons/issues/122) Support for parametrized OAuth2 Authentications in `@ParameterizedTest`. Sample usage (mind the `@JwtAuthenticationSource` and `@ParameterizedJwtAuth`):
+- [gh-122](https://github.com/ch4mpy/spring-addons/issues/122) Support for parametrized OAuth2 Authentications in `@ParameterizedTest`. **Mind the `@JwtAuthenticationSource` and `@ParameterizedJwtAuth`** in this sample (the first annotation defines the different authentication instances, the second inserts the one for the current test in the security context and provides it as test method parameter):
```java
@ParameterizedTest
@JwtAuthenticationSource({ @WithMockJwtAuth("NICE"), @WithMockJwtAuth("VERY_NICE") })
-void givenUserIsGrantedWithAnyJwtAuthentication_whenGetRestricted_thenOk(@ParameterizedJwtAuth JwtAuthenticationToken auth) throws Exception {
+void givenUserIsGrantedWithAnyNiceAuthority_whenGetRestricted_thenOk(@ParameterizedJwtAuth JwtAuthenticationToken auth) throws Exception {
api.perform(get("/restricted"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.body").value("You are so nice!"));
diff --git a/samples/tutorials/reactive-client/README.md b/samples/tutorials/reactive-client/README.md
index 7ce3ecb94..79bf8812d 100644
--- a/samples/tutorials/reactive-client/README.md
+++ b/samples/tutorials/reactive-client/README.md
@@ -244,12 +244,18 @@ static class DelegatingOidcClientInitiatedServerLogoutSuccessHandler implements
String postLogoutRedirectUri) {
delegates = StreamSupport.stream(clientRegistrationRepository.spliterator(), false)
.collect(Collectors.toMap(ClientRegistration::getRegistrationId, clientRegistration -> {
- final var registrationProperties = properties.getRegistration().get(clientRegistration.getRegistrationId());
- if (registrationProperties == null) {
+ final var endSessionEnpoint = (String) (clientRegistration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint"));
+ if (StringUtils.hasText(endSessionEnpoint)) {
final var handler = new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository);
handler.setPostLogoutRedirectUri(postLogoutRedirectUri);
return handler;
}
+ final var registrationProperties = properties.getRegistration().get(clientRegistration.getRegistrationId());
+ if (registrationProperties == null) {
+ throw new MisconfigurationException(
+ "OAuth2 client registration \"%s\" has no end_session_endpoint in OpenID configuration nor spring-addons logout properties"
+ .formatted(clientRegistration.getRegistrationId()));
+ }
return new AlmostOidcClientInitiatedServerLogoutSuccessHandler(registrationProperties, clientRegistration, postLogoutRedirectUri);
}));
}
@@ -262,7 +268,7 @@ static class DelegatingOidcClientInitiatedServerLogoutSuccessHandler implements
}
```
-This handler switches between Spring's `OidcClientInitiatedServerLogoutSuccessHandler` and our `AlmostOidcClientInitiatedServerLogoutSuccessHandler` depending on the configuration properties.
+This handler switches between Spring's `OidcClientInitiatedServerLogoutSuccessHandler` (used if the `.well-known/openid-configuration` exposes an `end_session_endpont`) and our `AlmostOidcClientInitiatedServerLogoutSuccessHandler` (if the logout configuration properties are present, or throws an exception).
Last we need to update the security filter-chain to use the new `DelegatingOidcClientInitiatedServerLogoutSuccessHandler`:
```java
diff --git a/samples/tutorials/reactive-client/src/main/java/com/c4soft/springaddons/tutorials/WebSecurityConfig.java b/samples/tutorials/reactive-client/src/main/java/com/c4soft/springaddons/tutorials/WebSecurityConfig.java
index 182a0f753..0497e54ce 100644
--- a/samples/tutorials/reactive-client/src/main/java/com/c4soft/springaddons/tutorials/WebSecurityConfig.java
+++ b/samples/tutorials/reactive-client/src/main/java/com/c4soft/springaddons/tutorials/WebSecurityConfig.java
@@ -1,5 +1,7 @@
package com.c4soft.springaddons.tutorials;
+import static org.springframework.security.config.Customizer.withDefaults;
+
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@@ -45,12 +47,14 @@
import org.springframework.security.web.server.authentication.logout.RedirectServerLogoutSuccessHandler;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
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;
+import com.c4soft.springaddons.tutorials.WebSecurityConfig.AuthoritiesMappingProperties.MisconfigurationException;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
@@ -69,7 +73,7 @@ SecurityWebFilterChain clientSecurityFilterChain(
InMemoryReactiveClientRegistrationRepository clientRegistrationRepository,
LogoutProperties logoutProperties) {
http.addFilterBefore(loginPageWebFilter(), SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING);
- http.oauth2Login();
+ http.oauth2Login(withDefaults());
http.logout(logout -> {
logout.logoutSuccessHandler(
new DelegatingOidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository, logoutProperties, "{baseUrl}"));
@@ -189,12 +193,18 @@ public DelegatingOidcClientInitiatedServerLogoutSuccessHandler(
String postLogoutRedirectUri) {
delegates = StreamSupport.stream(clientRegistrationRepository.spliterator(), false)
.collect(Collectors.toMap(ClientRegistration::getRegistrationId, clientRegistration -> {
- final var registrationProperties = properties.getRegistration().get(clientRegistration.getRegistrationId());
- if (registrationProperties == null) {
+ final var endSessionEnpoint = (String) (clientRegistration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint"));
+ if (StringUtils.hasText(endSessionEnpoint)) {
final var handler = new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository);
handler.setPostLogoutRedirectUri(postLogoutRedirectUri);
return handler;
}
+ final var registrationProperties = properties.getRegistration().get(clientRegistration.getRegistrationId());
+ if (registrationProperties == null) {
+ throw new MisconfigurationException(
+ "OAuth2 client registration \"%s\" has no end_session_endpoint in OpenID configuration nor spring-addons logout properties"
+ .formatted(clientRegistration.getRegistrationId()));
+ }
return new AlmostOidcClientInitiatedServerLogoutSuccessHandler(registrationProperties, clientRegistration, postLogoutRedirectUri);
}));
}
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/BearerAuthenticationSource.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/BearerAuthenticationSource.java
index e3de94753..874834c86 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/BearerAuthenticationSource.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/BearerAuthenticationSource.java
@@ -31,6 +31,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see ParameterizedBearerAuth
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/JwtAuthenticationSource.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/JwtAuthenticationSource.java
index 1e06c1d7b..516934c65 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/JwtAuthenticationSource.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/JwtAuthenticationSource.java
@@ -31,6 +31,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see ParameterizedJwtAuth
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OAuth2LoginAuthenticationSource.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OAuth2LoginAuthenticationSource.java
index 2e1577d99..66fe9f9e1 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OAuth2LoginAuthenticationSource.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OAuth2LoginAuthenticationSource.java
@@ -31,6 +31,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see ParameterizedOAuth2Login
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OidcLoginAuthenticationSource.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OidcLoginAuthenticationSource.java
index fba6afd8a..5990e8d87 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OidcLoginAuthenticationSource.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OidcLoginAuthenticationSource.java
@@ -31,6 +31,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see ParameterizedOidcLogin
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OpenIdAuthenticationSource.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OpenIdAuthenticationSource.java
index 69ac3ed09..dec249a8e 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OpenIdAuthenticationSource.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/OpenIdAuthenticationSource.java
@@ -32,6 +32,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see ParameterizedOpenId
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedBearerAuth.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedBearerAuth.java
index 5a45b8c91..badea4b37 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedBearerAuth.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedBearerAuth.java
@@ -26,6 +26,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see BearerAuthenticationSource
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedJwtAuth.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedJwtAuth.java
index 9826600ba..052497ee1 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedJwtAuth.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedJwtAuth.java
@@ -26,6 +26,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see JwtAuthenticationSource
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOAuth2Login.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOAuth2Login.java
index e6ded63bb..a8a5fb47a 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOAuth2Login.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOAuth2Login.java
@@ -26,6 +26,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see OAuth2LoginAuthenticationSource
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOidcLogin.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOidcLogin.java
index 9401ba3df..6f5648154 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOidcLogin.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOidcLogin.java
@@ -26,6 +26,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see OidcLoginAuthenticationSource
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOpenId.java b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOpenId.java
index 0ef2a155c..370564a2a 100644
--- a/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOpenId.java
+++ b/spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/parameterized/ParameterizedOpenId.java
@@ -28,6 +28,7 @@
*
* @author Jerome Wacongne ch4mp@c4-soft.com
* @see OpenIdAuthenticationSource
+ * @since 6.1.12
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)