swagger return `Whitelabel Error Page` for url `../swagger-ui.html` - spring-boot

I followed this link: a Chinese introduction article, according to it, I only need to add the dependencies in pom.xml. (./v2/api-docs has been always working.)
It used to work, but today it breaks.
my swagger dependencies in pom.xml file
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
I am using spring boot 2.3.3, and swagger 2.9.2 .

in SwaggerConfig.java,
add below codes:
#Configuration
#EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
...
#Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}

With newer versions of spring boot, this can be achieved with a property:
spring.resources.static-locations=classpath:/static/,classpath:/static/vendor/,classpath:/static/custom/
Also, make sure you configure SpringSecurity class to accept requests to this resources
#Override
public void configure(WebSecurity web)
{
web.ignoring()
.antMatchers( "/static/**","/resources/**", "/js/**", "/css/**", "/images/**");
}

Related

How can I bypass authentication for Swagger-UI?

How can I bypass token authentication for Swagger-UI from browser?
I can make requests to Swagger-UI via Postman.
When I make a request from the browser, I get an error because it requests a token.
http://localhost:8080/swagger-ui/index.html
How can I fix?
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
Main class
#SpringBootApplication
public class ExampleMain {
public static void main(String[] args) {
SpringApplication.run(ExampleMain.class, args);
}
}
Security class
#Configuration
#EnableWebSecurity
public class SecurityConfig {
private JwtConverter wtConverter;
public SecurityConfig(JwtConverter jwtConverter) {
this.jwtConverter = jwtConverter;
}
#Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/swagger-ui/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtConverter);
return http.build();
}
}
Apart from /swagger-ui/**, you should also permit access to OpenAPI documentation and Swagger resources:
...antMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**", "/swagger-resources").permitAll()

Spring Boot Admin UI login redirects either back to login page either to a "variables.css" file

Recently I have integrated Spring Boot Admin in my application. Everything fine, until I've stared adding security (nothing complicated, just Basic Auth). When I try to login in Spring Boot Admin UI, it redirects me back to the login page with "Login required to access the resource (Error: 401).", or to "variables.css". I am using Spring Boot 3.0.0 with Spring Boot Admin version 3.0.0-M6.
I have to mention that everything works alright if I disable spring security.
Security Config class looks like this:
#Configuration(proxyBeanMethods = false)
#EnableWebSecurity
#AllArgsConstructor
public class AdminSecurityConfig {
private final AdminServerProperties adminServerProperties;
private final SecurityProperties securityProperties;
private final AuthenticationConfiguration authenticationConfiguration;
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(this.adminServerProperties.path("/"));
http
.authorizeHttpRequests(
(authorizeRequests) ->
authorizeRequests.requestMatchers(this.adminServerProperties.path("/assets/**")).permitAll()
.requestMatchers(this.adminServerProperties.path("/*.css")).permitAll()
.requestMatchers(this.adminServerProperties.path("/actuator/info")).permitAll()
.requestMatchers(this.adminServerProperties.path("/actuator/health")).permitAll()
.requestMatchers(this.adminServerProperties.path("/login")).permitAll()
.anyRequest().authenticated()
).formLogin(
(formLogin) -> formLogin.loginPage(this.adminServerProperties.path("/login")).successHandler(successHandler).and()
).logout((logout) -> logout.logoutUrl(this.adminServerProperties.path("/logout")))
.httpBasic(Customizer.withDefaults())
.csrf(
(csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminServerProperties.path("/instances"),
HttpMethod.POST.name()),
new AntPathRequestMatcher(this.adminServerProperties.path("/instances/*"),
HttpMethod.DELETE.name()),
new AntPathRequestMatcher(this.adminServerProperties.path("/actuator/**"))
));
return http.build();
}
#Bean
public AuthenticationManager authenticationManager() throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
#Bean
public UserDetailsService userDetailsService() {
UserDetails user =
User.withUsername(securityProperties.getUser().getName())
.password("{noop}" + securityProperties.getUser().getPassword())
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
also, I have added this in the application.yaml file
spring:
security:
user:
name: ****
password: ****
roles:
- USER
boot:
admin:
monitor:
status-interval: 30000
status-lifetime: 30000
ui:
title: "Invoice Matching Admin"
remember-me-enabled: false
Main class looks like this:
#EnableAdminServer
#SpringBootApplication
public class InvoiceAdminServiceApplication {
public static void main(String[] args) {
SpringApplication.run(InvoiceAdminServiceApplication.class, args);
}
}
pom.xml contains this dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
In case that somebody will encounter the same problem, I managed to find the solution.
In the filterChain method you should add this:
.dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll()
Here is a documentation (https://codecentric.github.io/spring-boot-admin/3.0.0-M7/security.html#securing-spring-boot-admin) for Spring Admin security.

In my SpringBoot app I keep getting error 403 on /swagger-ui

I know this may be a duplicated question but I've already tried all the solutions on the existing ones. In my project I have imported these dependencies:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
I configure swagger with this class:
#Configuration
#EnableSwagger2
#EnableWebMvc
public class SwaggerConfiguration implements WebMvcConfigurer{
#Bean
public Docket api() {
var logger = LoggerFactory.getLogger(SwaggerConfiguration.class);
logger.info("configuring swagger");
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
I have both .antMatchers("/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**" ,"/swagger.json").permitAll()
and web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**");
because the internet couldn't make up it's mind on which should be used, but nothing works, if I go at /v2/api-docs I get some json wall-text with all my endpoints tho

How to run hazelcast session replication using vaadin4spring?

I am writing a simple demo application using hazelcast session replication based on the shared security example
mentioned in here https://github.com/peholmst/vaadin4spring.
The problem is that if i am starting the application it stays on the login site with "communication error".
With vaadin debug on, it shows me "Response didn't contain a server id. Please verify that the server is up-to-date and that the response data has not been modified in transmission."
In the IDE no stack trace is shown.
I tried also the working example here https://vaadin.com/blog/microservices-high-availability, but it didn´t give me a hint how to integrate hazelcast with vaadin4spring.
Here is my configuration:
public void configure(AuthenticationManagerBuilder auth) throws Exception {
User.UserBuilder users = User.withDefaultPasswordEncoder();
auth.inMemoryAuthentication().withUser("user").password("{noop}user").roles("USER")
.and()
.withUser("admin").password("{noop}admin").roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); // Use Vaadin's built-in CSRF protection instead
http.authorizeRequests().antMatchers("/login/**").anonymous()
.antMatchers("/vaadinServlet/UIDL/**").permitAll()
.antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll().anyRequest().authenticated();
http.httpBasic().disable();
http.formLogin().disable();
// Remember to add the VaadinSessionClosingLogoutHandler
http.logout().addLogoutHandler(new VaadinSessionClosingLogoutHandler()).logoutUrl("/logout")
.logoutSuccessUrl("/login?logout").permitAll();
http.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));
// Instruct Spring Security to use the same RememberMeServices as Vaadin4Spring. Also remember the key.
//http.rememberMe().rememberMeServices(rememberMeServices()).key("myAppKey");
// Instruct Spring Security to use the same authentication strategy as Vaadin4Spring
http.sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy());
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/VAADIN/**");
}
/**
* The {#link AuthenticationManager} must be available as a Spring bean for Vaadin4Spring.
*/
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* The {#link SessionAuthenticationStrategy} must be available as a Spring bean for Vaadin4Spring.
*/
#Bean
public SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new SessionFixationProtectionStrategy();
}
#Bean(name = VaadinSharedSecurityConfiguration.VAADIN_AUTHENTICATION_SUCCESS_HANDLER_BEAN)
VaadinAuthenticationSuccessHandler vaadinAuthenticationSuccessHandler(HttpService httpService,
VaadinRedirectStrategy vaadinRedirectStrategy) {
return new VaadinUrlAuthenticationSuccessHandler(httpService, vaadinRedirectStrategy, "/");
}
#Bean
public HazelcastInstance hazelcastInstance() {
MapAttributeConfig attributeConfig = new MapAttributeConfig()
.setName(HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
.setExtractor(PrincipalNameExtractor.class.getName());
Config config = new Config();
config.setProperty("hazelcast.max.no.heartbeat.seconds", "60")
.getMapConfig("spring:session:sessions")
.addMapAttributeConfig(attributeConfig)
.addMapIndexConfig(new MapIndexConfig(HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
config.getGroupConfig().setName("admin");
return Hazelcast.newHazelcastInstance(config);
}
pom snippet:
<java.version>1.8</java.version>
<vaadin.version>8.7.2</vaadin.version>
<spring-boot-ext.version>2.0.0.RELEASE</spring-boot-ext.version>
</properties>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-hazelcast</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.vaadin.spring.extensions</groupId>
<artifactId>vaadin-spring-ext-boot</artifactId>
<version>${spring-boot-ext.version}</version>
</dependency>
<dependency>
<groupId>org.vaadin.spring.extensions</groupId>
<artifactId>vaadin-spring-ext-security</artifactId>
<version>${spring-boot-ext.version}</version>
</dependency>
<dependency>
<groupId>org.vaadin.spring.extensions</groupId>
<artifactId>vaadin-spring-ext-core</artifactId>
<version>${spring-boot-ext.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Unable to load bootstrap on webpage after implementing spring security

I am using spring boot with the bootstrap dependency. After implementing a portion of code I am unable to load my webpage with bootstrap (the page will load but it will not utilize bootstrap). I am using the spring bootstrap dependency. Anyone have similar results using spring boot and thymeleaf?
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers().permitAll().anyRequest().authenticated().and().formLogin()
.loginPage("/login").permitAll().and().logout().permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
If the problem if reportet to css I use a configuration like this
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityContext extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http....
.and()
.authorizeRequests()
.antMatchers(LOG_IN_URL_PAGE,
LOG_OUT_URL_PAGE,
"/css/**",
"/js/**",
"/img/**",
"/**/favicon.ico",
"/webjars/**",
"/signup").permitAll()
.antMatchers("/**").fullyAuthenticated()
.anyRequest().authenticated();
}
...
}
webjars dependency in my pom
<!--static assets-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.11.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>select2</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>select2-bootstrap-css</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>1.3.15</version>
</dependency>
I use a configuration like this in a my open source projects and works for me
the key point is that you have say at Spring Secuirty that don't secure the resource url
for the resorce url Spring boot autoconfiguration make the work for you it is the motivation of webjars as sample of usage
you can see the complete set of avaiable webjars at the link http://www.webjars.org/
I hope that this can help you

Resources