I've looked in so many questions on here, but with no solutions that work for me.
I have a service that I want to run open api and the swagger ui on.
I have no problems running them without security, and when I try add basic authentication with the code below it works as I'd like, BUT it also puts all my other API's behind the same authentication, which I do not want. I thought I could add an additional requestMatcher like this:
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests()
.requestMatchers("/swagger-ui/**",
"/v3/api-docs/**",
"/v3/api-docs",
"/swagger-ui.html")
.hasRole("USER")
.requestMatchers("/**").permitAll()
.and()
.httpBasic(Customizer.withDefaults());
return httpSecurity.build();
}
When I do this, my other API's are. accessible without security as I expect, and when I go to the swagger ui I get the popup, I can log in, but then the get request to /v3/api-config fails with a 403 forbidden error or a 400 error, depending on where the permitAll requestMatcher is located.
What is the correct way to do this?
I want the swagger api's to be behind basic auth, but all other api's to be accessible by anyone.
I cannot find an existing answer to help with this.
My current security config is below, this blocks everything and allows swagger after authentication:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
public static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests()
.requestMatchers("/swagger-ui/**",
"/v3/api-docs/**",
"/v3/api-docs",
"/swagger-ui.html")
.hasRole("USER")
.and()
.httpBasic(Customizer.withDefaults());
return httpSecurity.build();
}
@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
For having authentication on swagger only, i've implemented two different filter chains. One for swagger and the other for the whole service. this is how my SecurityConfig looks like:
As you can see i've SSOAuthFilter for my whole service and SwaggerAuthFilter for swagger purposes only.
You'll also need a AuthenticationProvider:
And this is how my SwaggerAuthFilter looks like:
Hope that this helps you resolve your issue!