Swagger UI: Unable to infer baseurl, No Spring Security - java

We are getting the unable to infer base url when we tried to access the swagger url
We use Spring 5.3.18 and we don't use spring security.
We are using the Spring fox 3.0.0 version, and below is the Swagger Config and Web Config code.
#Profile("swagger")
#Configuration
#EnableSwagger2
#Import(SpringDataRestConfiguration.class)
public class SwaggerConfig {
private static final String DEFAULT = "1. Default";
#Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("basepackage.rest.controller"))
.paths(PathSelectors.any()).build();
}
}
#EnableWebMvc
#Configuration
#Profile("swagger")
public class WebConfig implements WebMvcConfigurer {
#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/");
}
}

Related

How to disable CORS in Spring Security within Spring Boot?

I want to completely remove CORS from Spring Boot (2.3.3.RELEASE) with Spring Security.
There is WebSecurityConfigurerAdapter#configure method for HttpSecurity object where I can call cors().disable() but it seems not to work.
class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().disable();
}
}
With just above snippet I still get CORS errors while accessing endpoints from my frontend application.
Instead of that I have to override addCorsMappings from WebMvcConfigurer interface like below 👇.
Why is that? Why it is not enough to call http.cors().disable()?
class MySecurityConfiguration extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("*");
}
Hi you need to create a global cors configuration in your spring boot project.Create a class and annotate it with #Configuration. You can follow this example below.
#Configuration
public class MyConfiguration {
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
};
}
}
Here is the full guide that spring framework provides https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

The type WebMvcConfigurerAdapter is deprecated

I just migrate to spring mvc version 5.0.1.RELEASE but suddenly in eclipse STS WebMvcConfigurerAdapter is marked as deprecated
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
// to serve static .html pages...
registry.addResourceHandler("/static/**").addResourceLocations("/resources/static/");
}
....
}
How can i remove this!
Since Spring 5 you just need to implement the interface WebMvcConfigurer:
public class MvcConfig implements WebMvcConfigurer {
This is because Java 8 introduced default methods on interfaces which cover the functionality of the WebMvcConfigurerAdapter class
See here:
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.html
I have been working on Swagger equivalent documentation library called Springfox nowadays and I found that in the Spring 5.0.8 (running at present), interface WebMvcConfigurer has been implemented by class WebMvcConfigurationSupport class which we can directly extend.
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
public class WebConfig extends WebMvcConfigurationSupport { }
And this is how I have used it for setting my resource handling mechanism as follows -
#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/");
}
In Spring every request will go through the DispatcherServlet. To avoid Static file request through DispatcherServlet(Front contoller) we configure MVC Static content.
Spring 3.1. introduced the ResourceHandlerRegistry to configure ResourceHttpRequestHandlers for serving static resources from the classpath, the WAR, or the file system. We can configure the ResourceHandlerRegistry programmatically inside our web context configuration class.
we have added the /js/** pattern to the ResourceHandler, lets include the foo.js resource located in the webapp/js/ directory
we have added the /resources/static/** pattern to the ResourceHandler, lets include the foo.html resource located in the webapp/resources/ directory
#Configuration
#EnableWebMvc
public class StaticResourceConfiguration implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("WebMvcConfigurer - addResourceHandlers() function get loaded...");
registry.addResourceHandler("/resources/static/**")
.addResourceLocations("/resources/");
registry
.addResourceHandler("/js/**")
.addResourceLocations("/js/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new GzipResourceResolver())
.addResolver(new PathResourceResolver());
}
}
XML Configuration
<mvc:annotation-driven />
<mvc:resources mapping="/staticFiles/path/**" location="/staticFilesFolder/js/"
cache-period="60"/>
Spring Boot MVC Static Content if the file is located in the WAR’s webapp/resources folder.
spring.mvc.static-path-pattern=/resources/static/**
Use org.springframework.web.servlet.config.annotation.WebMvcConfigurer
With Spring Boot 2.1.4.RELEASE (Spring Framework 5.1.6.RELEASE), do like this
package vn.bkit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; // Deprecated.
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
public class MvcConfiguration implements WebMvcConfigurer {
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}

Spring boot Internationalization ?lang=en has no effect

I'm currently working on a Web-App using Spring boot (including spring security) and thymeleaf. At the moment i'm trying to integrate internationalization support for the languages english and german as a start.
For the basics I've followed this Tutorial and tried to get their example to work.
Now if I go to Localhost:8443/international and choose one of the languages the URL gets built correctly to .../international?lang=en. Thymeleaf even reads the fields in the .propperties file marked as default. But I can't get it to actually switch the language no matter what I do.
Code:
#Configuration
#EnableWebMvc
#EnableAutoConfiguration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.US);
return slr;
}
}
Like this I assume it's taking the default messages.propperties. However if I put the LocaleResolver Bean into my
public class Application extends SpringBootServletInitializer
class where the main method is, it takes whatever language is set as default Locale there.
From where I am at right now I conclude that my .propperties files are fine and can be read but something with the LocaleChangeInterceptor does not work propperly. I went into debug mode but any breakpoints in the WebConfig class did not trigger at all.
One assumption of mine would be Spring security messing something up, such that the ?lang request can't be resolved. (Tried both logged-in and logged-out).
Would be really glad if anyone has some idea on how to resolve the issue, thanks for every reply in advance!
My Application class:
#SpringBootApplication
#EnableMongoRepositories(basePackageClasses = UserRepository.class)
#ComponentScan(basePackages = { "my.company.controller", "my.company.Services", "java.lang.String","my.company.Services.Security" })
#EnableConfigurationProperties(my.company.Services.Storage.StorageProperties.class)
public class Application extends SpringBootServletInitializer {
#Autowired
private UserRepository repository;
#Autowired
private SecUserDetailsService userDetailService;
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Bean
CommandLineRunner init(StorageService storageService) {
return (args) -> {
repository.deleteAll();
userDetailService.addUser("bob", "ross", "admin");
userDetailService.addUser("1", "1", "superuser");
userDetailService.addUser("2", "2", "admin");
System.out.println("All users currently in DB:");
System.out.println("-------------------------------");
for (User user1 : repository.findAll()) {
System.out.println(user1);
}
System.out.println();
// storageService.deleteAll();
try {
storageService.init();
} catch (StorageException e) {
System.out.println("Ordner schon vorhanden");
}
};
//If i add this here french gets picked as default language, changing does still not work
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.FRENCH);
return slr;
}
}
Try removing the #ComponentScan annotation. The #SpringBootApplication does the component scanning automatically. I guess your WebConfig class is not loaded.

Add Bean and Interceptor to the context of an application from an external jar

I have a web application with the following configuration class:
#Configuration
#EnableWebMvc
#EnableSpringDataWebSupport
class CustomMvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public MyBean myBean() {
return new MyBean();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}
}
I want to add a dependency of a jar on the application, add another bean and another interceptor to the context.In another project I have another WebMvcConfigurerAdapter class but it does not run:
#Configuration
#EnableWebMvc
#EnableSpringDataWebSupport
class OtherCustomMvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public OtherBean otherBean() {
return new OtherBean();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor());
}
}
If I try to inject the OtherBean into a class of the application web does not exist in context:
#Inject
private OtherBean otherBean;
And the CustomInterceptor does not run. How can I add beans and interceptors to an application from an external module?
I think you just need to add proper #Include annotation to your MVC Configuration.
#Include(OtherCustomMvcConfiguration.class)
class CustomMvcConfiguration extends WebMvcConfigurerAdapter {
...
}

Java config for spring interceptor where interceptor is using autowired spring beans

I want to add spring mvc interceptor as part of Java config. I already have a xml based config for this but I am trying to move to a Java config. For interceptors, I know that it can be done like this from the spring documentation-
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor());
}
}
But my interceptor is using a spring bean autowired into it like follows-
public class LocaleInterceptor extends HandlerInterceptorAdaptor {
#Autowired
ISomeService someService;
...
}
The SomeService class looks like follows-
#Service
public class SomeService implements ISomeService {
...
}
I am using annotations like #Service for scanning the beans and have not specified them in the configuration class as #Bean
As my understanding, since java config uses new for creating the object, spring will not automatically inject the dependencies into it.
How can I add the interceptors like this as part of the java config?
Just do the following:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
LocaleInterceptor localInterceptor() {
return new LocalInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeInterceptor());
}
}
Of course LocaleInterceptor needs to be configured as a Spring bean somewhere (XML, Java Config or using annotations) in order for the relevant field of WebConfig to get injected.
The documentation for general customization of Spring's MVC configuration can be found here, and specifically for Interceptors see this section
When you handle the object creation for yourself like in:
registry.addInterceptor(new LocaleInterceptor());
there is no way the Spring container can manage that object for you and therefore make the necessary injection into your LocaleInterceptor.
Another way that could be more convenient for your situation, is to declare the managed #Bean in the #Configuration and use the method directly, like so:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public LocaleInterceptor localeInterceptor() {
return new LocaleInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor( localeInterceptor() );
}
}
Try to inject your service as a constructor parameter. It is simple.
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Autowired
ISomeService someService;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor(someService));
}
}
Then reconfigure your interceptor,
public class LocaleInterceptor extends HandlerInterceptorAdaptor {
private final ISomeService someService;
public LocaleInterceptor(ISomeService someService) {
this.someService = someService;
}
}
Cheers !

Categories