I am not using Spring Boot. I am using simply Spring MVC, Spring Security and Tomcat 10 As Server.
spring-webmvc: 6.0.3
spring-security-web & spring-security-config: 6.0.1
My Question is how my spring security config gets loaded into my Spring Web Application Context.
As we do not explicitly load it.
I have one class in classpath
which only extends AbstractSecurityWebApplicationInitializer
to initialize spring security filters.
Below is my code for SpringSecurityConfigClass, MySecurityConfig
class.
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
@Bean
public InMemoryUserDetailsManager inMemoryUserDetails() {
UserDetails admin = User.builder()
.username("admin")
.password("{noop}admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(admin);
}
}
Now as we can see, SpringSecurityConfigClass, MySecurityConfig
class is annotated with @Configuration
and @EnableWebSecurity
.
Now as this is a Configuration
where do we load it to our Spring Application Context/Web Application Context.
Now I know this is not a Spring Core Application, where we will load the Spring Configuration class into our Application Context using AnnotationConfigApplicationContext
but in spring MVC also we do mention our Servlet config class.
Below is my code for Servlet Configuration class, AppConfig
class.
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.soumyadip.springSecurity")
public class AppConfig {
@Bean
public ViewResolver vieResolver() {
InternalResourceViewResolver myViewResolver = new InternalResourceViewResolver();
myViewResolver.setPrefix("/WEB-INF/views/");
myViewResolver.setSuffix(".jsp");
return myViewResolver;
}
}
And here is my code for DispatcherServletConfigClass
,
public class MyDispatcherServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class[] {AppConfig.class};
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] {"/"};
}
}
Here as we can see there are two methods, getRootConfigClasses
and getServletConfigClasses
.
And via getServletConfigClasses
method we are returing our ServletConfiguration
class.
And this code works as expected, i.e. I am needing to input the password and user name.
As per the answer.
Spring's ApplicationContext provides the capability of loading multiple (hierarchical) contexts
Basically there can be two WebApplicationContext
that gets loaded into Spring ApplicationContext
in a hierarchy.
Servlet WebApplicationContext
where Servlet Specific configuration such asControllers
get loaded, the configuration class for this context is loaded viagetServletConfigClasses
method.Root WebApplicationContext
where Spring Infra related configuration is loaded, such asSpringSecurityConfig
, and it is loaded viagetRootConfigClasses
method.
Also according to the answer, and many more tutorials available online, it suggested to return SpringSecurityConfigClass via getRootConfigClasses
method, i.e. doing below:
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class[] {MySecurityConfig.class};
}
But As I told I am not having to do the above to get MySpringSecurity config loaded into application context.
So I believe the magic happens due to @EnableWebSecurity
annotation.
Is my understanding Correct?
Then what is the need of returning SecurityConfig via getRootConfigClasses
, is there any difference if we do not?
If I remove the @EnableWebSecurity
annotation, but return the Configuration class via getRootConfigClasses
like above, the application does not work.
So @EnableWebSecurity
is must.
I feel stupid for asking this but could not find any satisfactory answer on SO/Internet.
I was expecting that either it will be must to, return MySecuirityConfig
class via getRootConfigClasses
method, as we have to do for SpringServletConfig
class.