I am developing a Spring application that starts an embedded Jetty Server. It then "deploys" a Spring MVC web app to this Jetty server.
All is working well with multiple controllers, but I fail to add Spring Security to the web app. I use programmatic and annotation-based configuration and the Jetty server is configured like this:
Server server = new Server(8080);
server.setStopAtShutdown(true);
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.mypackage.web");
context.setParent(mainContext);
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setErrorHandler(null);
contextHandler.setContextPath("/");
DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
DefaultServlet staticServlet = new DefaultServlet();
contextHandler.addServlet(new ServletHolder(dispatcherServlet), "/");
contextHandler.addServlet(new ServletHolder("staticServlet", staticServlet), "/res");
contextHandler.addEventListener(new ContextLoaderListener(context));
contextHandler.setResourceBase("webapp");
server.setHandler(contextHandler);
I also created a class com.mypackage.web.SecurityConfig that extends WebSecurityConfigurerAdapter
and overrides the configure method like so:
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();
}
}
As far as I understand the documentation, this should be enough to "lock down" my application. When I start the application in debug mode, a breakpoint gets hit in the configure method, so Spring seems to detect the config class.
However, I can still access any page in my application without getting redirected to the default login form.
Do I need to tell the Jetty Servlet container about this config or am I missing something else?
To enable Spring Security integration with Spring MVC add the @EnableWebSecurity annotation to your configuration. Spring Security provides the configuration using Spring MVC's WebMvcConfigurer.
The first thing you need to do is add Spring Security to the classpath. The WebSecurityConfig class is annotated with @EnableWebSecurity to enable Spring Security's web security support and provide the Spring MVC integration.
Okay, so what I missed is that I need to add Spring's DelegatingFilterProxy to Jetty's ServletContextHandler. The usual Spring way is to extend AbstractSecurityWebApplicationInitializer, which will add the Filter Proxy. This unfortunately also didn't work with Jetty.
One can add the Filter Proxy manually to Jetty, though, with a call explained in this comment:
import static org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;
...
ServletContextHandler contextHandler = new ServletContextHandler();
...
contextHandler.addFilter(
new FilterHolder( new DelegatingFilterProxy( DEFAULT_FILTER_NAME ) ),
"/*",
EnumSet.allOf( DispatcherType.class ));
I also had to enable Session-Handling in Jetty, but this is explained very well here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With