Reputation: 93
i am creating a login page using spring web mvc with spring security. when i deploy the application in my local machine it is working as expected. the login page is loading without problem. But when i try to deploy the application in hosting provider, the login page took very long time to load before finally loaded successfully.
here is the message when i access the application
2017-04-02 18:16:30.482 INFO 28450 --- [p-nio-80-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 43 ms
and here is the message when the login page finally loaded
2017-04-02 18:25:01.135 INFO 28450 --- [p-nio-80-exec-1] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [510,546] milliseconds.
i am using spring 1.4.5, build with maven and running the application with java -jar
here is my application.properties content
# other
server.port=8082
spring.session.store-type=none
spring.jpa.properties.hibernate.jdbc.time_zone = UTC+7
MvcConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("dashboard");
registry.addViewController("/login").setViewName("login");
registry.addViewController("/403").setViewName("403");
registry.addViewController("/404").setViewName("404");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.addResourceLocations("/static/")
.addResourceLocations("/static/**")
.addResourceLocations("/resources/static/")
.addResourceLocations("/resources/static/**")
.addResourceLocations("/")
.addResourceLocations("/**");
}
}
WebSecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomAccountDetailsService.class)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
@Bean(name = "passwordEncoder")
public PasswordEncoder passwordencoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/layout/**").permitAll()
.antMatchers("/calendar").hasAuthority("USER")
.antMatchers("/customer").hasAuthority("ADMIN")
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and().csrf();
}
}
hosting provider machine : Ubuntu Server 16.04.2 LTS RAM 4GB HDD : 40GB SSD and 3TB
after the page successfully loaded, then the page is not taking long time anymore to load if i refresh it. but if i change the server.port
in application.properties
and restarting the application (Ctrl + C and java -jar again), the very same thing is happenned again.
i don't understand what makes the loading time in the hosting machine took very long if compared to my local machine. any pointer for what should be done or check would be very helpful
Upvotes: 0
Views: 1526
Reputation: 11875
When SecureRandom
initializes, it takes some bytes from the system random number generator. On Linux, Java takes those from /dev/random which blocks if the system does not have enough entropy (until the system gets that entropy). This may take a while.
The solution is to switch to /dev/urandom
, which does not block.
One of the possible solutions is add the following to your java commandline:
-Djava.security.egd=file:/dev/./urandom
Note that dot between /dev/ and /urandom: this is not a typo. This is required (or at least was required with some java versions): https://security.stackexchange.com/questions/14386/what-do-i-need-to-configure-to-make-sure-my-software-uses-dev-urandom
Upvotes: 1