Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded Jetty doesn't recognise Spring MVC Security

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?

like image 664
feob Avatar asked Jun 18 '15 23:06

feob


People also ask

Can we use Spring Security with Spring MVC?

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.

How do I enable HTTP Security in spring?

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.


1 Answers

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.

like image 175
feob Avatar answered Oct 27 '22 11:10

feob