zer0
zer0

Reputation: 93

Spring web mvc security took long time to finish loading page

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

Answers (1)

Roman Puchkovskiy
Roman Puchkovskiy

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

Related Questions