Where is SpringBootServletInitializer's DispatcherServlet? - spring

How SpringBootServletInitializer determines RootConfig.class, WebConfig.class, and maps DispatcherSevlet?

#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
return application.sources(Application.class); - loads the Application.class. That's your main configuration, where you can declare #Beans. You can add more #Configuration classes by putting them in the same folder, for example, and they will be "component-scanned".
If you declare a #Configuration class that extends WebMvcConfigurerAdapter, you have an access to the web configuration like resource handlers, argument resolvers, etc.
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public-resources/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new FooBarHandlerMethodArgumentResolver());
}
}
By default the dispatcher servlet is configured to the root path "/"
If you need more details, see the auto configuration.

Related

How to add scanBasePackages in SpringBootServletInitializer & SpringApplicationBuilder?

Following is used for my spring project
#SpringBootApplication(scanBasePackages = "com.tv")
public class WWWAbacusApplication {
public static void main(String[] args) {
SpringApplication.run(WWWAbacusApplication.class, args);
}
}
I need to deploy it in widlfly so i do it like below
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WWWAbacusApplication.class);
}
}
but i never required scanbasepackages but in this application i required it.
Can anyone suggest how to do it in SpringBootServletInitializer

Couldn't access jpg file under resources/static folder

I couldn't access the image under the resources/static folder. I'm using Spring Boot version 2.112.
I also tried adding spring.resources.static-locations in the properties file but still can't access the .jpg file from the resources/static/image folder. Any reason why?
#Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
#Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/", "classpath:/image/");
}
Well, you may try https://stackoverflow.com/a/66361120/15215155. Most of time is about spring boot default security configuration.
Edit: Little edit here since it would be too much for comments.
Tackling the problem from another angle. Is there any specific feature you need from WebMvcConfigurationSupport?? If not, why not trying WebSecurityConfigurer for the resources handlers and WebSecurityConfigurerAdapter for the security config?.
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**", "/js/**")
.addResourceLocations("classpath:/static/", "classpath:/resources/static/");
registry.addResourceHandler("/images/**").addResourceLocations("classpath:/static/images/");
}
}
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/image/**"").permitAll()
}
}

Diffrent way of implementation security ends with the same error

I have implemented an application with combination Spring Boot and Angular 4. I put all Angular files under /resources/static directory:
static directory
Then I added to Spring Security classes:
#Configuration
#EnableWebMvc
#ComponentScan("com.inventory")
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/static/**")
.addResourceLocations("classpath:/resources/static/");
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index.html");
}
}
and:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated();
}
and it seem that everythings should work. Unfortunately whenever I run my app it throws exception:
There was an unexpected error (type=Internal Server Error, status=500).
Could not resolve view with name 'index.html' in servlet with name 'dispatcherServlet'.
Of course I tried diffrent solution like adding this:
#Controller
public class ViewController {
#RequestMapping(value = "/#/")
public String index() {
return "forward:/index.html";
}
#RequestMapping(value = "/")
public String home() {
return "forward:/index.html";
}
}
But nothing works. Does anyone has a clue what else can I do?
When using Spring boot normally you don't have to configure resource handler manually, spring boot will automatically load contents from the following loc:
/static
/public
/resources
/META-INF/resources
see spring boot guides on loading static contents

How to exclude a URL when usinf PCF SSO service with EnableOAuth2Sso annotation?

I am using Angular and Spring Boot to build a Single Page app with Rest API. Here is my configuration:
#SpringBootApplication
#EnableOAuth2Sso
public class AppConfig extends SpringBootServletInitializer implements ApplicationContextAware {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
public static void main(String[] args) {
ApplicationContext appContext = SpringApplication.run(AppConfig.class);
context = appContext;
}
#Configuration
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/healthcheck", "/").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated();
}
}
}
The SSO service I am using is provided by Pivotal Cloud Foundry[PCF]. Everything was fine before I included
SecurityConfig
class. As soon as the app is loaded, user is redirected to the SSO login page and then redirected back to the app. But I need to exclude the "healthcheck" URL from authentication. That is why I included the SecurityConfig class. But now the SSO Authentication is not working at all. I could only reach /healthcheck.
I followed this example https://spring.io/guides/tutorials/spring-boot-oauth2/
Can someone please let me know what is wrong with my code?
Thanks.
I figured it out. I had to move my EnableOAuth2Sso to the WebSecurityConfigurerAdapter. Like this:
#SpringBootApplication
public class AppConfig extends SpringBootServletInitializer implements ApplicationContextAware {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
public static void main(String[] args) {
ApplicationContext appContext = SpringApplication.run(AppConfig.class);
context = appContext;
}
#Configuration
#EnableOAuth2Sso
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/healthcheck", "/").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated();
}
}
}

Global method security in Spring Boot

I'm having some issues when trying to enable the global method security in a Spring Boot application.
More or less I've this configuration:
#ComponentScan
#Configuration
#EnableAutoConfiguration
#EnableConfigurationProperties
public class Main extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(Main.class);
app.setShowBanner(false);
ApplicationContext context = app.run(args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Main.class);
}
}
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
...
}
#Override
protected void configure(HttpSecurity http) throws Exception {
...
}
}
#Controller
public class SampleController {
#RequestMapping("/api/hello")
#ResponseBody
String hello() {
return "Hello!";
}
#Secured(SecurityGrant.WRITE_PROJECT)
#RequestMapping("/api/bye")
#ResponseBody
String bye() {
return "Bye!";
}
}
The #Secure annotations are working OK at services, but not in controllers, so as I read here (http://docs.spring.io/spring-security/site/faq/faq.html#faq-method-security-in-web-context) I think is because method security is only configured in the root application context and not in the one for the servlet.
However, I can't find the way to set this via Java Configuration, instead of using a web.xml file.
Any ideas?
Update:
As pointed in the comments, methods should be public to be proxied.
The controller methods need to be public in order to be proxied for #Secured. Just doing that should fix it.
In XML you would have to define a second global-method-security in the servlet-context.xml file. This is because there are two contexts, the root context and the web context and security needs to be configured in each separately.
In Java config, try to create a separate web configuration class, and mark it with #EnableWebMvc:
#Configuration
#EnableWebMvc
#EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebConfig {
...
}

Resources