Skip to content

Commit

Permalink
gh-213 native images compatibility of @ConfigurationProperties
Browse files Browse the repository at this point in the history
  • Loading branch information
ch4mpy committed May 16, 2024
1 parent 7a203a7 commit 703d255
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 173 deletions.
8 changes: 1 addition & 7 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,10 @@

## Breaking News

Just added a [Sponsor this project](https://ko-fi.com/ch4mpy) link to the repo ;-)
In `7.7.0`, some `@ConfigurationProperties` were changed to inner-class definition (instead of standing in a source file of their own). Migration should be no more complicated than organizing imports.

The OAuth2 BFF tutorial is now [on Baeldung](https://www.baeldung.com/spring-cloud-gateway-bff-oauth2). It was deeply refreshed in the process and now contains samples for Angular, React (Next.js) and Vue (Vite).

In `7.6.0`, the experimental support for `RestClient` and `WebClient` builders as well as `@HttpExchange` (the successor of `@FeignClient`) is moved to a dedicated starter: [`spring-addons-starter-rest`](https://github.com/ch4mpy/spring-addons/tree/master/spring-addons-starter-rest). As a reminder, it helps to get pre-configured client builders and `@HttpExchange` proxies with this clients

`7.5.0` comes with an important refactoring of the way JWT decoder(s) configuration is resolved. This greatly eases ["dynamic" multi-tenant scenarios implementation](https://github.com/ch4mpy/spring-addons/tree/master/spring-addons-starter-oidc#1-1-4). The only noticeable breaking change is the removal of `SpringAddonsOidcProperties::getOpProperties`. This feature is now the responsibility of the newly introduced `OpenidProviderPropertiesResolver`. The default implementation resolves properties with an exact match on issuer (just as `getOpProperties` was doing). As usual, auto-configured bean backs-off if you expose one to use another properties resolving strategy.

**Important warning for those using `@WithJwt` (and since `7.3.0`, `@WithMockJwtAuth`) but not `spring-addons-starter-oidc`**: you should expose your JWT converter as a bean. See [`spring-addons-oauth2-test` README](https://github.com/ch4mpy/spring-addons/tree/master/spring-addons-oauth2-test) for details.

## [OIDC starter](https://github.com/ch4mpy/spring-addons/tree/master/spring-addons-starter-oidc)

With `spring-addons-starter-oidc`, you might need 0 Java conf, even in scenarios like:
Expand Down
5 changes: 5 additions & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## `7.x` Branch

### `7.7.0`
- [gh-213](https://github.com/ch4mpy/spring-addons/issues/213): native-images compatibility:
- add missing `@NestedConfigurationProperty` to `SpringAddonsOidcProperties#client` and `SpringAddonsOidcProperties#resourceserver`
- declare all other `@ConfigurationProperty` as nested classes of either `SpringAddonsOidcProperties`, `SpringAddonsOidcClientProperties` or `SpringAddonsOidcResourceServerProperties`

### `7.6.11`
- Spring Boot `3.2.4`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import org.springframework.util.StringUtils;

import com.c4_soft.springaddons.security.oidc.starter.OpenidProviderPropertiesResolver;
import com.c4_soft.springaddons.security.oidc.starter.properties.OpenidProviderProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties;

@Configuration
@EnableMethodSecurity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;

import com.c4_soft.springaddons.security.oidc.starter.properties.OpenidProviderProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties;
import com.c4_soft.springaddons.security.oidc.starter.synchronised.ServletConfigurationSupport;
import com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.ResourceServerExpressionInterceptUrlRegistryPostProcessor;
import com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.ResourceServerSynchronizedHttpSecurityPostProcessor;
Expand Down
2 changes: 1 addition & 1 deletion spring-addons-starter-oidc/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This project is a Spring Boot starter to use in addition to `spring-boot-starter

```xml
<properties>
<springaddons.version>7.6.11</springaddons.version>
<springaddons.version>7.7.0</springaddons.version>
</properties>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import org.springframework.security.oauth2.jwt.JwtClaimNames;

import com.c4_soft.springaddons.security.oidc.starter.properties.OpenidProviderProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties;

import lombok.RequiredArgsConstructor;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.springframework.util.StringUtils;

import com.c4_soft.springaddons.security.oidc.starter.properties.NotAConfiguredOpenidProviderException;
import com.c4_soft.springaddons.security.oidc.starter.properties.SimpleAuthoritiesMappingProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties.SimpleAuthoritiesMappingProperties;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;

Expand All @@ -22,8 +22,8 @@
* Portable converter to extract Spring-security authorities from OAuth2 claims.
* </p>
* <p>
* It relies on {@link OpenidProviderPropertiesResolver} to resolve the configuration properties for the provided claims (and throws if it is not resolved).
* This properties enable to configure:
* It relies on {@link OpenidProviderPropertiesResolver} to resolve the configuration properties for the provided claims (and throws if it
* is not resolved). This properties enable to configure:
* </p>
* <ul>
* <li>source claims (which claims to pick authorities from, dot.separated.path is supported)</li>
Expand All @@ -35,33 +35,33 @@
*/
@RequiredArgsConstructor
public class ConfigurableClaimSetAuthoritiesConverter implements ClaimSetAuthoritiesConverter {
private final OpenidProviderPropertiesResolver opPropertiesResolver;
private final OpenidProviderPropertiesResolver opPropertiesResolver;

@Override
public Collection<? extends GrantedAuthority> convert(@NonNull Map<String, Object> source) {
final var opProperties = opPropertiesResolver.resolve(source).orElseThrow(() -> new NotAConfiguredOpenidProviderException(source));
// @formatter:off
@Override
public Collection<? extends GrantedAuthority> convert(@NonNull Map<String, Object> source) {
final var opProperties = opPropertiesResolver.resolve(source).orElseThrow(() -> new NotAConfiguredOpenidProviderException(source));
// @formatter:off
return opProperties.getAuthorities().stream()
.flatMap(authoritiesMappingProps -> getAuthorities(source, authoritiesMappingProps))
.map(r -> (GrantedAuthority) new SimpleGrantedAuthority(r)).toList();
// @formatter:on
}
}

private static String processCase(String role, SimpleAuthoritiesMappingProperties.Case caze) {
switch (caze) {
case UPPER: {
return role.toUpperCase();
}
case LOWER: {
return role.toLowerCase();
}
default:
return role;
}
}
private static String processCase(String role, SimpleAuthoritiesMappingProperties.Case caze) {
switch (caze) {
case UPPER: {
return role.toUpperCase();
}
case LOWER: {
return role.toLowerCase();
}
default:
return role;
}
}

private static Stream<String> getAuthorities(Map<String, Object> claims, SimpleAuthoritiesMappingProperties props) {
// @formatter:off
private static Stream<String> getAuthorities(Map<String, Object> claims, SimpleAuthoritiesMappingProperties props) {
// @formatter:off
return getClaims(claims, props.getPath())
.flatMap(claim -> Stream.of(claim.split(",")))
.flatMap(claim -> Stream.of(claim.split(" ")))
Expand All @@ -70,29 +70,29 @@ private static Stream<String> getAuthorities(Map<String, Object> claims, SimpleA
.map(r -> processCase(r, props.getCaze()))
.map(r -> String.format("%s%s", props.getPrefix(), r));
// @formatter:on
}
}

@SuppressWarnings({ "rawtypes", "unchecked" })
private static Stream<String> getClaims(Map<String, Object> claims, String path) {
try {
final var res = JsonPath.read(claims, path);
if (res instanceof String r) {
return Stream.of(r);
}
if (res instanceof List l) {
if (l.size() == 0) {
return Stream.empty();
}
if (l.get(0) instanceof String) {
return l.stream();
}
if (l.get(0) instanceof List) {
return l.stream().flatMap(o -> ((List) o).stream());
}
}
return Stream.empty();
} catch (PathNotFoundException e) {
return Stream.empty();
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Stream<String> getClaims(Map<String, Object> claims, String path) {
try {
final var res = JsonPath.read(claims, path);
if (res instanceof String r) {
return Stream.of(r);
}
if (res instanceof List l) {
if (l.size() == 0) {
return Stream.empty();
}
if (l.get(0) instanceof String) {
return l.stream();
}
if (l.get(0) instanceof List) {
return l.stream().flatMap(o -> ((List) o).stream());
}
}
return Stream.empty();
} catch (PathNotFoundException e) {
return Stream.empty();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.Map;
import java.util.Optional;

import com.c4_soft.springaddons.security.oidc.starter.properties.OpenidProviderProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties;

/**
* Resolves OpenID Provider configuration properties from OAuth2 / OpenID claims (decoded from a JWT, introspected from an opaque token or
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 703d255

Please sign in to comment.