Skip to content

Commit

Permalink
Single spring-addons starter
Browse files Browse the repository at this point in the history
  • Loading branch information
ch4mpy committed Jul 9, 2023
1 parent ee40e16 commit bb176f2
Show file tree
Hide file tree
Showing 327 changed files with 3,469 additions and 6,383 deletions.
47 changes: 47 additions & 0 deletions 7.0.0-migration-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Migration Guide from 6.x to 7.0.0

## Dependencies
- replace any spring-addons starter with `com.c4-soft.springaddons:spring-addons-starter-oidc`
- replace any spring-addons test starter with `com.c4-soft.springaddons:spring-addons-starter-oidc-test`
- depending or your needs, add a dependency to
* `org.springframework.boot:spring-boot-starter-oauth2-resource-server` for a REST API secured with access tokens
* `org.springframework.boot:spring-boot-starter-oauth2-client` when configuring `spring-cloud-gateway` as BFF or exposing server-side rendered templates with frameworks like Thymeleaf
* both of above when exposing publicly both a REST API secured with access tokens and other resources secured with sessions

## Java Sources

### Main Code
- rename `SpringAddonsSecurityProperties` to `SpringAddonsOidcProperties`. Also, if using nested properties, rename
* `getIssuers()` to `getOps()`
* `getLocation()` to `getIss()`
- replace `SpringAddonsOAuth2ClientProperties` with `SpringAddonsOidcProperties::getClient` (only `SpringAddonsOidcProperties` can be autowired)
- organize imports

### Tests
- replace `@AutoConfigureAddonsSecurity` with `@AutoConfigureAddonsMinimalSecurity`
- replace `@AutoConfigureAddonsWebSecurity` with one of:
* `@AutoConfigureAddonsWebmvcSecurity`
* `@AutoConfigureAddonsWefluxSecurity`

## Application Properties
This is probably the most tedious part of the migration. Hopefully, your IDE auto-completion and syntax highliting should help you there.

### Common Configuration
- rename `com.c4-soft.springaddons.security` to `com.c4-soft.springaddons.oidc`
- rename `issuers` to `ops` which stands for OpenID Providers (`com.c4-soft.springaddons.security.issuers` becomes `com.c4-soft.springaddons.oidc.ops`)
- rename OpenID Providers `location` to `iss`: if set, the is used to add an "issuer" (tokens `iss` claim) validator to JWT decoder (`com.c4-soft.springaddons.security.issuers[].location` becomes `com.c4-soft.springaddons.oidc.ops[].iss`)
- rename`audience` to `aud`: if set, the is used to add an "audience" (tokens `aud` claim) validator to JWT decoder (`com.c4-soft.springaddons.security.issuers[].aud` becomes `com.c4-soft.springaddons.oidc.ops[].aud`)

CORS configuration has also improved for both clients and resource servers: `allowed-origin-patterns` is used instead of `allowed-origins`. This is a requirement for using `allow-credentials` and is also more flexible: you can define ant patterns like `https://*.my-domain.pf`.
- rename `allowed-origins` to `allowed-origin-patterns`
- add `allow-credentials` and `max-age` if it makes sens (this are added configuration options)

### Resource Servers
Resource server `Security(Web)FilterChain` can now be completely disabled with `com.c4-soft.springaddons.security.resourceserver.enabled=false`

Resource server specific properties are grouped in a new `resourceserver` subset:
- move `cors` down 1 level into `resourceserver` (`com.c4-soft.springaddons.security.cors` becomes `com.c4-soft.springaddons.security.resourceserver.cors`)
- move `permit-all` down one level to `resourceserver` (`com.c4-soft.springaddons.security.permit-all` becomes `com.c4-soft.springaddons.security.resourceserver.permit-all`)

### Clients
- rename `allowed-origins` to `allowed-origin-patterns` (`com.c4-soft.springaddons.security.client.cors.allowed-origins` becomes `com.c4-soft.springaddons.security.client.cors.allowed-origin-patterns`)
71 changes: 42 additions & 29 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
Do not hesitate to fork this repo and send pull requests, even for things as small as a typo in READMEs or Javadoc. This would promote you as contributor.
7.0.0 is a break through in usability: all 6 `spring-addons` Boot starters are merged into a single one: [`com.c4-soft.springaddons:spring-addons-starter-oidc`](https://repo1.maven.org/maven2/com/c4-soft/springaddons/spring-addons-starter-oidc/), and so are the 4 test libs: [`com.c4-soft.springaddons:spring-addons-starter-oidc-test`](https://repo1.maven.org/maven2/com/c4-soft/springaddons/spring-addons-starter-oidc-test/) (if you are using just the test annotations, without the starter, the dependency is still the same: [`com.c4-soft.springaddons:spring-addons-oauth2-test`](https://repo1.maven.org/maven2/com/c4-soft/springaddons/spring-addons-oauth2-test/)).

# Spring-addons
Please follow the [migration guide](https://github.com/ch4mpy/spring-addons/blob/master/7.0.0-migration-guide.md) to bump from `6.x` to `7.0.0`. Also, all samples and tutorials are migrated to latest starter and test annotations.

# Configuring and Testing OAuth2 / OpenID Spring applications Made Easy
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`. **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:
- providing with annotations to mock OAuth2 `Authentication` for JUnit `@Test`:
* `@WithMockAuthentication` with `@AuthenticationSource` and `@ParameterizedAuthentication` companions for JUnit 5 @ParameterizedTest
* `@WithJwt` which uses the JWT authentication converter defined in security configuration to build the right type of `Authentication` (with the right authorities and name) based on a JSON file on he classpath (or plain Java String
* `@WithOpaqueToken` same as `@WithJwt` for introspection, using the `OpaqueTokenAuthenticationConverter` in the security configuration
* more specialized annotations for specific authentication implementations (`@WithOAuth2Login`, `@WithOidcLogin`, etc.) or to use as elements for your own test annotations in applications using custom OAuth2 `Authentication` implementations
- pushing OIDC auto-configuration to the next level in Spring Boot 3 applications. 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
* sessions & CSRF disabled by default on resource server and enabled on clients. If a cookie repo is chosen for CSRF (as required by Angular, React, Vue, etc.), then the right request handler is configured and a filter to actually set the cookie is added
Expand All @@ -16,7 +22,7 @@ The libraries hosted in this repo shine in two domains:

Jump to:
- [1. Unit & Integration Testing With Security](#unit-tests)
- [2. Spring Boot OAuth2 Starters](#oauth2-starters)
- [2. Spring Boot OIDC Starter](#oauth2-starters)
- [3. Where to Start](#start)
- [4. Versions & Requirements](#versions)
- [5. Additional Modules](#additional-modules)
Expand All @@ -32,6 +38,7 @@ An [article covering the usage of OAuth2 test annotations from this lib](https:/

However, since this article was published, test annotations have improved.

### 1.1. Sample
Let's consider the following secured `@Service`
```java
@Service
Expand All @@ -51,8 +58,7 @@ Now, let's assume that you have a staging environment with a few representative
`@WithJwt` and `@WithOpaqueToken` enable to load those claim-sets and turn it into `Authentication` instances using the authentication converter from your security configuration, and as so, with the same type, authorities, name and claims as at runtime.
```java
@AutoConfigureAddonsSecurity
@EnableAutoConfiguration(exclude = { AddonsWebSecurityBeans.class, SpringAddonsOAuth2ClientBeans.class }) // Only AddonsSecurityBeans is required for this test
@AddonsWebmvcComponentTest
@SpringBootTest(classes = { SecurityConfig.class, MessageService.class })
class MessageServiceTests {
Expand Down Expand Up @@ -86,22 +92,28 @@ class MessageServiceTests {
}
```
There are we few things worth noting above:
- annotation fit so well with BDD (given-when-then) and are very brief
- annotations fit so well with BDD (given-when-then): the test pre-conditions (given) are decorating the test instead of cluttering its content like MockMvc request post-processors and WebTestClient mutators
- annotations can be very brief and expressive
- we are testing a `@Service` having methods decorated with `@PreAuthorize` (without `MockMvc` or `WebTestClient`)
- the claims are loaded from a JSON files in the test classpath
- we are using JUnit 5 `@ParameterizedTest`: the test will run once for each of the authentication in the stream provided by the `identities` method
- the claim used as `username` is a potentially a nested claim resolved with JSON-Path
- the claim used as `username` potentially is a nested claim resolved with JSON-Path
### 1.2. Which Dependency / Annotation to Use
`spring-addons-oauth2-test` is enough to use test annotations, but if you opted for `spring-addons-starter-oidc`, then `spring-addons-starter-oidc-test` is better suited as it comes with tooling to load spring-addons auto-configuration during tests (refer to the many samples for usage).
`@WithMockAuthentication` should be enough to test applications with RBAC (role-based access control): it allows to easily define `name` and `authorities`, as well as the Authentication an principal types to mock if your application code expects something specific.
In case your access-control uses more than just name and authorities, and you'll probably need to define claim-set details. `@WithJwt` and `@WithOpaqueToken` can come pretty handy as it uses the respectively the JWT or OpaqueToken authentication converter in your security configuration to build the authentication instance, using a JSON payload from the classpath (or a plain Java String): you might just dump payloads of access tokens for representative users in test resources (use a tool like https://jwt.io to easily get those payloads).
## 2. <a name="oauth2-starters"/>Spring Boot Starter
**This starters is designed to push auto-configuration to the next level** and does nothing more than helping you with auto-configuration from application properties.
## 2. <a name="oauth2-starters"/>Spring Boot Starters
**This starters are designed to push auto-configuration to the next level** (and does nothing more than helping you with auto-configuration from applicationproperties). In most cases, you should need 0 Java conf. An effort was made to make [tutorials](https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials), Javadoc and modules READMEs as informative as possible. Please refer there for more details.
In most cases, you should need 0 Java conf. An effort was made to make [tutorials](https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials), Javadoc and modules READMEs as informative as possible. Please refer there for more details.
Spring Boot starters are 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)
- [spring-addons-webflux-introspecting-resource-server](https://github.com/ch4mpy/spring-addons/tree/master/webflux/spring-addons-webflux-introspecting-resource-server) to be used in reactive REST APIs secured with access token introspection
- [spring-addons-webflux-jwt-resource-server](https://github.com/ch4mpy/spring-addons/tree/master/webflux/spring-addons-webflux-jwt-resource-server) to be used in **reactive REST APIs secured with JWT decoders**
- [spring-addons-webmvc-client](https://github.com/ch4mpy/spring-addons/tree/master/webmvc/spring-addons-webmvc-client) to be used in servlet applications rendering templates on the server (Thymeleaf, JSF, etc.)
- [spring-addons-webmvc-introspecting-resource-server](https://github.com/ch4mpy/spring-addons/tree/master/webmvc/spring-addons-webmvc-introspecting-resource-server) to be used in servlet REST APIs secured with access token introspection
- [spring-addons-webmvc-jwt-resource-server](https://github.com/ch4mpy/spring-addons/tree/master/webmvc/spring-addons-webmvc-jwt-resource-server) to be used in **servlet REST APIs secured with JWT decoders**
`spring-addons-oidc-starter` does not replace `spring-boot-starter-oauth2-resource-server` and `spring-boot-starter-oauth2-client`, it defines a few beans designed to be picked by it.
If you are curious enough, you might inspect what is auto-configured (and under which conditions) by reading the source code, starting from the [org.springframework.boot.autoconfigure.AutoConfiguration.imports](https://github.com/ch4mpy/spring-addons/blob/master/spring-addons-starter-oidc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports) file, which is the Spring Boot standard entry-point defining what is loaded when a jar is on the classpath.
## 3. <a name="start"/>Where to Start
[Tutorials](https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials) which cover:
Expand All @@ -119,38 +131,34 @@ Spring Boot starters are thin wrappers around `spring-boot-starter-oauth2-resour
* `OAuthentication<OpenidClaimSet>` / Spring default `Authentication` implementation (`JwtAuthenticationToken` for JWT decoder or `BearerTokenAuthentication` for token introspection)
## 4. <a name="versions"/>Versions & Requirements
6.x branch is designed for spring-boot 3 and requires JDK 17 as minimum.
If locked wtih a lower JDK or spring-boot version, you'll have to use a 5.4.x release wich are made with **JDK 1.8** and spring 2.6 (boot auto loading mechanisms have change with 2.7). But be aware that some of the features documented on main branch can be missing or behave differently.
6.x and 7.X branch are designed for spring-boot 3 and requires JDK 17 as minimum.
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
<properties>
<springaddons.version>6.2.0</springaddons.version>
<app-type>webmvc</app-type><!-- alternative value is webflux !-->
<token>jwt</token><!-- alternative value is introspecting !-->
<springaddons.version>7.0.0</springaddons.version>
</properties>
<dependencies>
<!-- to pull resource-server stater with its companion for unit-tests -->
<!-- to pull addons stater with its companion for unit-tests -->
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-addons-${app-type}-${token}-resource-server</artifactId>
<artifactId>spring-addons-starter-oidc</artifactId>
<version>${springaddons.version}</version>
</dependency>
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-addons-${app-type}-${token}-test</artifactId>
<artifactId>spring-addons-starter-oidc-test</artifactId>
<version>${springaddons.version}</version>
<scope>test</scope>
</dependency>
<!-- If you don't want starters but need @WithMockJwtAuth or WithMockBearerTokenAuthentication -->
<!-- instead of the two preceding, you can pull test annotations only -->
<!-- If you don't want to use the starter but need test annotations -->
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-addons-oauth2-test</artifactId>
<version>${springaddons.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down Expand Up @@ -180,6 +188,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.
### 7.0.0
See the [migration guide](https://github.com/ch4mpy/spring-addons/blob/master/7.0.0-migration-guide.md)
- merge all 6 starters into a single one
- reduce test libs count to 2: one with just annotations and another to ease testing of apps using the starter
### 6.2.0
- remove `OAuth2AuthenticationFactory`: instead, use `Converter<Jwt, ? extends AbstractAuthenticationToken>`, `Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>>`, `OpaqueTokenAuthenticationConverter` or `ReactiveOpaqueTokenAuthenticationConverter`
- create `@WithJwt` to build OAuth2 `Authentication` during tests, using a JSON string or file on the classpath and submitting it to the JWT authentication converter. All samples and tutorials are updated with this new annotation.
Expand Down
Loading

0 comments on commit bb176f2

Please sign in to comment.