I'm trying to limit access to the Swagger User Interface (UI) to specific roles (e.g. Swagger API user, System Admin user, etc...)
I tried the answer in this SO question - Restrict access to Swagger UI
So my code class looks like
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* XLogger.
*/
private static final XLogger LOG = XLoggerFactory.getXLogger(WebSecurityConfig.class);
@Value("${my.property.allowedOrigins}")
private String[] corsAllowedOrigins;
@Value("${my.property.excludeUrlPattern}")
private String[] excludeUrlPattern;
@Autowired
ApplicationContext applicationContext;
/**
* The AuthenticationSuccessHandler.
*/
@Autowired
HSSAuthenticationSuccessHandler authenticationSuccessHandler;
/**
* The runtime properties
*/
@Autowired
RuntimeProperties runtimeProperties;
@Override
protected void configure(HttpSecurity http) throws Exception {
LOG.entry(http);
String[] noAuthPermitAllPatterns = runtimeProperties.getApplicationProperties().getNoAuthPermitAllPatterns();
http.authorizeRequests()
.antMatchers("/swagger-ui/**", "/**/swagger-ui/**", "/v3/api-docs/**", "/**/v3/api-docs/**")
.hasRole("ADMIN").antMatchers(noAuthPermitAllPatterns).permitAll().anyRequest().authenticated().and()
.formLogin().failureHandler(authenticationFailureHandler()).successHandler(authenticationSuccessHandler)
.loginPage("/saml/login").permitAll().and().logout().logoutSuccessUrl("/logoutSuccess").permitAll()
.invalidateHttpSession(true).and().csrf().disable().cors()
.configurationSource(corsConfigurationSource());
http.addFilterBefore((MetadataGeneratorFilter) applicationContext.getBean("metadataGeneratorFilter"),
ChannelProcessingFilter.class).addFilterAfter(
(FilterChainProxy) applicationContext.getBean("samlFilter"), BasicAuthenticationFilter.class);
LOG.exit();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
LOG.entry();
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList(corsAllowedOrigins));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT"));
configuration.setAllowCredentials(true);
// the below three lines will add the relevant CORS response headers
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return LOG.exit(source);
}
@Override
@Bean(name = "webAuthenticationManagerBean")
public AuthenticationManager authenticationManagerBean() throws Exception {
LOG.entry();
return LOG.exit(super.authenticationManagerBean());
}
/**
* Authentication Failure Handler
*
* @return The Authentication Failure Handler
*/
@Bean(name = "authenticationFailureHandler")
protected AuthenticationFailureHandler authenticationFailureHandler() {
LOG.entry();
String defaultFailureUrl = runtimeProperties.getApplicationProperties().getDefaultFailureURL();
ExceptionMappingAuthenticationFailureHandler authFailureHandler = new ExceptionMappingAuthenticationFailureHandler();
authFailureHandler.setDefaultFailureUrl(defaultFailureUrl);
Map<String, String> mappings = new HashMap<>();
mappings.put("org.springframework.security.authentication.InternalAuthenticationServiceException",
defaultFailureUrl);
mappings.put("org.springframework.security.saml.SAMLAuthenticationToken", defaultFailureUrl);
mappings.put("org.springframework.security.authentication.AuthenticationServiceException", defaultFailureUrl);
authFailureHandler.setExceptionMappings(mappings);
return LOG.exit(authFailureHandler);
}
@Override
public void configure(WebSecurity web) throws Exception {
LOG.entry(web);
web.ignoring().antMatchers(excludeUrlPattern);
LOG.exit();
}
}
This still allows me to access the Swagger UI @
http://{localUrl}/swagger-ui/index.html?configUrl=/{localUrl}/v3/api-docs/swagger-config
Also, what's the difference between two configure( ) methods, where one uses HttpSecurity
and the other uses WebSecurity
? The excludeUrlPattern does include swagger patterns, so I wondered if that creates a conflict with what I'm trying to do.
I guess I'm expecting a 401 Unauthorized response. I'm totally new to Swagger, so any advice is appreciated!