Spring Boot and Spring Security integration in embedded Jetty environment - java

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?

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.

Related

server.servletPath=/* not working in spring-boot.version 2.1.7.RELEASE

I have been using the below property in the application.properties file with spring-boot.version 1.5.6.RELEASE without any issues.
server.servletPath=/*
This was a workaround to enable a method in a library class which uses the function getPathInfo() of javax.servlet.http.HttpServletRequest to get a valid value instead of null.
I had to go with this workaround since there is no support of that library jar anymore.
This workaround started failing when I upgraded my application to spring-boot.version 2.1.7.RELEASE
server.servletPath is changed to spring.mvc.servletPath from Spring Boot 2 onwards.
I tried setting the below property and it did not work
spring.mvc.servletPath=/*
I also tried the below function in my configuration class and it did not work.
#Bean
public DispatcherServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet,
ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(
dispatcherServlet, "/*");
registration.setName("dispatcherServlet");
registration.setLoadOnStartup(-1);
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}
Could you please provide a working solution for this property using spring-boot.version 2.1.7.RELEASE?
Thanks,
Dhinu
The correct setting for newer spring versions is:
spring.mvc.servlet.path=/some/path
This changes the mapping of the DispatcherServlet, so all resources served by spring are mapped to this path.
If you set:
server.servlet.contextPath=/some/path
The whole web context is changed.
The main difference is that setting the dispatcher servlet path allows you to register additional servlets on other paths while with context path set, spring boot's tomcat can only serve content below that context path.
Use the following config property on latest spring boot version:
server.servlet.contextPath=/*

Spring boot 2.1.0 error when trying to bootstrap Hibernate asynchronously

I'm upgrading my application to Spring 2.1.0 and one of the new things I was trying to use is Hibernate asynchronously bootstrap.
But when I'm adding a flag spring.data.jpa.repositories.bootstrap-mode=deferred to configuration then application throws error during startup:
Parameter 0 of method entityManagerFactory in
org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration
required a single bean, but 2 were found:
- [ ] - applicationTaskExecutor: defined by method 'applicationTaskExecutor' in class path resource
[org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfiguration.class]
- taskScheduler: defined by method 'taskScheduler' in class path resource
[org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.class]
Looks like Spring have trouble with finding unique AsyncTaskExecutor bean but both beans are coming from auto configuration.
To make it work I excluded TaskExecutionAutoConfiguration because right now I'm not using it but I don't really like this approach:
#SpringBootApplication(exclude = {TaskExecutionAutoConfiguration.class})
#EnableScheduling
class MyApp {}
Any ideas how to fix it properly? Seems to me like a bug in spring boot.

My actuators in spring boot are not working

I am trying to check whether my spring boot application is up and running via spring boot actuators. My spring boot application annotation contains this:
#SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
WebMvcAutoConfiguration.class,
HibernateJpaAutoConfiguration.class EntityManagerFactory
})
In my application properties file I have management.server.port=8081. But when I start up my application and try to run localhost:8081/actuator/info I got an error - This site can not be reached.
What am I doing wrong ?
Thank you for any help.

Adding Context to Spring Boot Embedded Tomcat

Is it possible to add a context to Spring Boot's embedded tomcat that can access the filesystem?
I'm trying to get the same functionality as adding <Context docBase="/path/to/my/files" path="/MyFiles"/> where the context is used for directly viewing/downloading files.
In Spring Boot I've managed to add a context with the following:
#Bean
public ServletWebServerFactory factory() {
return new TomcatServletWebServerFactory() {
#Override
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
tomcat.addContext("/MyFiles", "/path/to/my/files");
return super.getTomcatWebServer(tomcat);
}
};
}
However this context is only created/restricted to where Spring Boot puts the running tomcat in /private/var/folders/zy/T. Therefore any requests to that context just return a 404 because the file I'm asking for doesn't exists in /private/var...etc.
Is there any way to create the Tomcat context so that it has access to files elsewhere on the system?

Create spring boot restful Webservices without #EnableAutoconfig

I have a Spring boot project which is packaged into jar and it functionalities are related to MQ and database. I want to now host a webservice on that project however I cannot use #EnableAutoConfiguration or #SpringBootApplication. The webservice to be created is a simple GET service that will return a integer value. I have tried following steps but still the webservice doesnt start.
Added Spring-webmvc, spring-web, spring-boot-web ,spring-tomcat jars to pom.xml
Changed the artifact type from jar to war in pom.xml
Added #EnableWebMvc in the config class
Added a class with #Controller and #RequestMapping
Created a bean for EmbeddedServletContext for Tomcat.
What have I missed?
Some blogs mentioned about creating a WebApplicationContextInitializer and some mentioned about creating a Dispatcher servlet.
My question is what all beans do I need to manually create to bring up my webservice (as I cannot use EnableAutoConfig)

Categories