In Spring Boot, is it possible to authenticate clients using both OAuth2 and API Keys? Let's say I have an application with UI. The user logs in the UI and given a jwt token from an OAuth2 server. So the security config looks like this
...
http.authorizeRequests()
....
.anyRequest().authenticated().and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
The oauth2 server is configured in application.yml file.
Say, I want to expose some of the backend APIs to other clients and only authorized them by authenticating the API Key. Can I just add a addFilterBefore
in my security config? Does it mean it will authenticate both api key and oauth jwt?
http.addFilterBefore(new SomeApiKeyFilter(...))
....
.anyRequest().authenticated().and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
Is this possible? Cause when I tried to call an endpoint, it throws an error saying ... APIKeyAuthenticationToken cannot be cast to JwtAuthenticationToken
.
As @ch4mp told, you have to define two security configurations. I did It by adding two innerclasses (as a configuration) in my security configuration class instead of creating two Beans. Let me show you an example:
public class SecurityConfig {
@Configuration
@Order(1)
public static class DefaultSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.securityMatcher("/xxx/**")
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
...
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
}
@Configuration
@Order(2)
public static class OtherSecurityConfig {
@Bean
public SecurityFilterChain otherFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher("/yyy/**")
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin()
...;
return http.build();
}
}
}
You will get a form login if you try to access the yyy base path and 401 http error if you try the xxx base path.