1
votes

I'm trying to initialize Spring Security from a main() method in a "fat" executable JAR with Spring Boot and embedded Jetty. I use Spring Security with Java config (no web.xml). The problem is that embedded Jetty fails to register the springSecurityFilterChain filter.

When I run the same JAR as a WAR in Jetty (mvn jetty:run) it works normally and I see this:

Initializing Spring embedded WebApplicationContext

But when running in embedded Jetty I see no WebApplicationContext getting initialized.

I have this EmbeddedServletContainerFactory:

@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
    factory.setPort(8080);
    factory.addServerCustomizers(new JettyServerCustomizer() {
        public void customize(Server server) {    
        // TODO: INITIALIZE SPRING SECURITY SOMEHOW...
        }
    });
    return factory;
}

I've tried creating a subclass of AbstractSecurityWebApplicationInitializer but it is in conflict with my SpringBootServletInitializer. In my pom.xml I have these dependencies:

  • spring-boot-starter-jetty
  • spring-boot-starter-logging
  • spring-boot-starter

When I add spring-boot-web it throws:

java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling

Also I tried to register the DelegatingFilterProxy with Jetty but then it throws:

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

I'm guessing I need to tell Jetty to use WebApplicationContext, but how?

1
Why aren't you just creating a class with a main method to run your application? Spring boot will do the setup for you. See spring.io/guides/gs/securing-web and next to convert jar to war spring.io/guides/gs/convert-jar-to-warM. Deinum
I'm doing exactly that - just as the Spring Boot docs suggest. I just need to initialize Spring Security from main().albogdano
SPring boot will do that as well as bootstrapping the Jetty container. I don't see why you are creating a container yourself as spring boot does all that for you...M. Deinum
I use the ServletContainer to boot a Jersey ResourceConfig class.albogdano
Still don't see why you would need to do that yourself, create a JettyServerCustomizer register it as a bean in your context and spring boot will apply it for you. The port etc. will all be set by Spring Boot. You could also register the config as a ServletBean so that it would be registered by Spring Boot.M. Deinum

1 Answers

3
votes

Your setup disables Spring Boot to do its magic. Instead of setting up the container yourself let Spring Boot handle it. You can simply add your JettyServerCustomizer to the configuration as a @Bean. This will execute it and you can do your registration of whatever you need.

This still allows Spring Boot to do its magic and you have registered the additional endpoint y ou need.

Another solution could be to add the servlet as a ServletRegistrationBean to your configuration it will then automatically be added by Spring Boot.