Is spring multitenant OAuth2 resource server library. When spring resource server is used there is the possibility to configure one IdP. What if we need more IdP? There are some use cases from rewriting obsolete app to simple application which should work with more IdPs like Google, Facebook etc. without necessity to run Keycloak or similar SW in provider mode. Janus is the answer. With Janus, we can easily replace standard resource server, keep current configuration as is and simply add new IdPs.
Artifacts releases are available on maven central (and on pages indexing central):
This README contains only basic information about project. For more or detailed information, visit the wiki
First things first we have to add Maven dependency
<dependency>
<groupId>com.groocraft</groupId>
<artifactId>janus</artifactId>
<version>${version}</version>
</dependency>You will need the original spring resource server library. If you do not have it added yet, add it:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<version>${version}</version>
</dependency>There are two configuration needed. One is the configuration of IdPs, the other is configuration of web security with Janus.
In both cases you must use @EnableJanus or @EnableReactiveJanus if you do not have auto-configuration turned on.
As you can see the structure of resource server remains the same, but we can add more named IdPs:
spring:
security:
oauth2:
resourceserver:
first:
issuer-uri: ...
jwk-set-uri: ...
second:
issuer-uri: ...
jwk-set-uri: ...
roles-claim-name: realm_roles
roles-authority-prefix: REALM_ROLE
third:
issuer-uri: ...
jws-algorithm: PS512
public-key-location: 'classpath:key.pub'As you can see the configuration for IdPs supports JWK and local approach, all algorithms and customization of JWT parsing/translation to Authentication object.
There are more ways how to configure web security. WebSecurityAdapterConfigurer was standard for a long time, SecurityFilterChain is the new approach. The following provides examples how use Janus with both of them where we prefer the newer one. WARNING: From version 2.0.0 only SecurityFilterChain is present as Spring removed WebSecurityAdapterConfigurer
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, WithMultiIdPsCustomizer withMultiIdPs) {
return http.authorizeRequests().anyRequest().fullyAuthenticated().and()
.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.cors(Customizer.withDefaults())
.oauth2ResourceServer(withMultiIdPs)
.sessionManagement(c -> c
.sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy())
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)).build();
}
}With reactive security there is only one way to configured it, and it is very similar to the first way at the previous chapter:
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http, ReactiveWithMultiIdPsCustomizer withMultiIdPs) {
return http.authorizeExchange().anyExchange().authenticated().and()
.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.cors(Customizer.withDefaults())
.oauth2ResourceServer(withMultiIdPs).build();
}
}Testing with Janus should be smooth if you use full scope context with @SpringBootTest for example. If you are using @WebMvcTest you will need to add Janus manually as it will not be automatically enabled. For manual enabling, using @EnableJanus or @EnableReactiveJanus annotation.