Set of tools I find useful to work with Spring-framework. For now it is focused on spring-security with OAuth2, but could grow.
Use artifacts with jdk11 or jdk1.8 suffix if you can't bump to JDK 17 or above.
Note that only master branch hosts the archetype and older JDKs branches might stay behind JDK 17 one, so you'll have to check maven central to check which version is available for the artifacts you want to pull.
As I write this, latest version is 4.1.5 but I could forget to update before releasing, so please refer to maven central to pick latest available release of one of the following:
<properties>
<springaddons.version>4.1.5</springaddons.version>
</properties>
<dependencies>
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-addons-keycloak</artifactId>
<version>${springaddons.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-addons</artifactId>
<version>${springaddons.version}</version>
</dependency>
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-test-webflux-addons</artifactId>
<version>${springaddons.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-test-webmvc-addons</artifactId>
<version>${springaddons.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
This set of libraries is not just about @WithMockKeycloakAuth.
The main value here might be the tooling to provide portable and extensible OIDC implementations for spring-security (OidcIdAuthentication<OidcToken>) and spring-security-test (@Claims, @OpenIdClaims, etc.)
spring-security-oauth2-addonsCurrently limited to:
- OidcToken
- a portable OpenID Authentication implementation: OidcIdAuthentication, which is intended to be used with any OpenID authorization server: Keycoak, Auth0, MS Identity Server, ...
- default (configurable) web-security configuration for RESTful APIs: OidcReactiveApiSecurityConfig and OidcServletApiSecurityConfig. Defaults (which can be configured from configuration.propeties) are:
- CORS enabled to all routes (a REST API is not intended to serve UI)
- CSRF disabled
- anonymous enabled (but authentication required to all routes that is not included in permit-all property)
- authorities mapped from realm_access.roles with no transformation (no prefix, no case alteration)
- stateless sessions
- 401 (instead of redirection to login) if user is not authenticated (or authentication is invalid)
You can also find there a tutorial do write your own OIDC Authentication implementation and test annotation in case you need more than just authorities and OIDC claims to write your security rules.
spring-addons-keycloak@WithMockKeycloakAuth the most probable reason for you landing on this pagespring-security-oauth2-test-addonsCode common to webmvc and webflux test libs. This includes annotations allowing to tests not only @Controller but also any other kind of @Component (such as @Service):
- @WithMockOidcId achieves about the same thing as @WithMockKeycloakAuth, building a mocked OidcIdAuthentication (instead of KeycloakAuthenticationToken)
- @WithMockAuthentication to help (a bit, not as handy as the two others) inject a mocked Authentication of any type in test context
You don't need any other dependency to use @WithMockKeycloakAuth in your tests
spring-security-oauth2-test-webflux-addonsBuilds on top of spring-security-oauth2-test-addons, adding:
- "fluent" API for WebTestClient
- some tooling around WebTestClient: configurable default media-type and charset, requests shortcuts
spring-security-oauth2-test-webmvc-addonsBuilds on top of spring-security-oauth2-test-addons, adding:
- "fluent" API for MockMvc
- some tooling around MockMvc: configurable default media-type and charset, requests shortcuts
spring-webmvc-archetypeAn archetype to bootstrap a maven multi-module project focused on REST micro-services: - OpenID security - default conf providing with enabled CORS, disabled CSRF, stateless sessions, 401 instead of redirect to login, ... - Spring exception-handling - spring-native for smaller / faster booted services - bootstraped JPA and unit tests
I put quite a few spring-boot app samples in spring-security-oauth2-test-webmvc-addons and spring-security-oauth2-test-webflux-addons.
The reason why samples are in test sources (under src/test folders) is to keep jar small. It can, of course, be run / debug from within your favorite IDE.
I recommand you clone my repo and debug the samples with a REST client like Postman, so that you can hack the config and tests.
Adapting the samples to your Keycloak instance should be just a matter of editing application.properties.
Caveat do not narrow your exploration to keycloak sample just beacause you are using a Keycloak authorization-server:
I run all samples against a Keycloak instance.
Last, *RetrievingAuthoritiesFromDatabase samples retrieve authorities from a DB instead of extracting it from JWT claims. The key in the DB is the user "subject".
In that case, Keycloak authorisation-server is responsible for ensuring user ID only, authorities are the responsibility of the resource-server.
As a consequence, (to run only, not in unit-tests) those samples expect a database to be accessible and populated, which I can't do for you
as I can't know the "subject" claims for your test users registered in your Keycloak instance.
Main target is JDK 17. jdk1.8 and jdk11 branches will be maintained at least until spring-boot 3 is released.
keycloak-spring-boot-starter & keycloak-spring-security-adapter versionIf using Keycloak with version >= 9.0.2 and < 11.0.0, you need to add following bean to your conf because of a regression:
@Configuration
public class SpringBootKeycloakConfigResolver implements KeycloakConfigResolver {
private KeycloakDeployment keycloakDeployment;
private AdapterConfig adapterConfig;
@Autowired
public SpringBootKeycloakConfigResolver(AdapterConfig adapterConfig) {
this.adapterConfig = adapterConfig;
}
@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
if (keycloakDeployment != null) {
return keycloakDeployment;
}
keycloakDeployment = KeycloakDeploymentBuilder.build(adapterConfig);
return keycloakDeployment;
}
}
From 11.0.0 on, just @Import(KeycloakSpringBootConfigResolver.class) with @KeycloakConfiguration on your KeycloakWebSecurityConfigurerAdapter implementation.
2.0 comes with a noticeable amount of breaking changes. So lets start tracking features.
AuthenticationManagerResolver @Beans SpringAddonsSecurityPropertiesspring-addons-keycloakjdk1.8 and jdk11 branchesOidcToken specialisation (parse private claims in addition to authorities).OidcReactiveApiSecurityConfig and OidcServletApiSecurityConfig usability: ease security beans replacement (including authorities and authentication converter for use cases where OidcAuthentication is not enough)SecurityProperties to less conflicting SpringAddonsSecurityPropertiesAbstractOidc...ApiSecurityConfig into Oidc...ApiSecurityConfig with default authorities mapper being keycloak or Auth0 depending on com.c4-soft.springaddons.security.keycloak.client-id being set or notSecurityProperties@OpenIdClaims (gh-35).AbstractOidcReactiveApiSecurityConfig to spring-security-oauth2-addons. It provides with reasonable default WebSecurityConfig for a reactive (weblux) based API secured with OidcAuthentication.AbstractOidcServletApiSecurityConfig to spring-security-oauth2-addons. It provides with reasonable default WebSecurityConfig for a servlet based API secured with OidcAuthentication.claims = @OpenIdClaims(...)@WithMockJwtAuth in addition to @WithMockKeycloakAuth and @WithMockOidcAuthKeycloakOidcIdAuthenticationConverter with SynchronizedJwt2OidcIdAuthenticationConverter and complement it with ReactiveJwt2OidcIdAuthenticationConverterspring-security-oauth2-addons (implementations where mostly useless)@JsonObjectClaim and @JsonArrayClaim to configure complex private claims. Sample: @WithMockKeycloakAuth(otherClaims = @ClaimSet(jsonObjectClaims = @JsonObjectClaim(name = "foo", value = "{\"bar\":\"bad\", \"nested\":{\"deep\":\"her\"}, \"arr\":[1,2,3]}"))) or @WithMockOidcId(privateClaims = @JsonObjectClaim(name = "foo", value = "{\"bar\":\"bad\", \"nested\":{\"deep\":\"her\"}, \"arr\":[1,2,3]}"))privateClaims to otherClaims in @WithMockKeycloakAuthGrantedAuthoritiesMapper is now optional in test config. Defaulted to NullAuthoritiesMapperServletKeycloakAuthUnitTestingSupport::keycloakAuthenticationToken() to authentication() to improve API fluidity (api.with(keycloak.authentication()).get(...))@IdTokenClaims and @OidcStandardClaims@WithMockKeycloakAuthOidcId::getName() returns subject claim instead of preferred_usernamename with subject in @WithMockOidcIdname from @WithMockKeycloakAuth with preferedUsername in @WithAccessToken@WithMockOidcId and @WithMockKeycloakAuth (claims with values of type int, long, String and String[] only)@WithAccessToken with @WithKeycloakIDToken instead of repeting properties (AccessToken extends IDToken)@WithMockKeycloakAuth sample usage in spring-security-oauth2-test-addons README$ claude mcp add spring-addons \
-- python -m otcore.mcp_server <graph>