Spring web mvc 安全性需要很长时间才能完成页面加载

Spring web mvc security took long time to finish loading page

我正在使用具有 spring 安全性的 spring web mvc 创建登录页面。当我在我的本地机器上部署应用程序时,它按预期工作。登录页面加载没有问题。但是当我尝试在托管服务提供商中部署应用程序时,登录页面在加载成功之前花费了很长时间。

这是我访问应用程序时的消息

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

这是登录页面最终加载时的消息

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.

我正在使用 spring 1.4.5,使用 Maven 和 运行 使用 java -jar

构建应用程序

这是我的application.properties内容

# 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();
    }

}

托管提供商机器: Ubuntu 服务器 16.04.2 LTS 内存 4GB 硬盘:40GB 固态硬盘和 3TB

页面加载成功后,如果我刷新页面,页面加载时间不会再长。但是如果我更改 application.properties 中的 server.port 并重新启动应用程序(再次按 Ctrl + C 和 java -jar),同样的事情又会发生。

我不明白是什么导致主机上的加载时间比我的本地机器要长。 任何关于应该做什么或检查的指示都会非常有帮助

SecureRandom初始化时,它从系统随机数生成器中获取一些字节。在 Linux 上,Java 获取来自 /dev/random 的那些,如果系统没有足够的熵(直到系统获得该熵),哪些阻塞。这可能需要一段时间。

解决方法是切换到/dev/urandom,不阻塞

可能的解决方案之一是将以下内容添加到您的 java 命令行:

-Djava.security.egd=file:/dev/./urandom

请注意 /dev/ 和 /urandom 之间的点:这不是拼写错误。这是必需的(或者至少某些 java 版本是必需的):https://security.stackexchange.com/questions/14386/what-do-i-need-to-configure-to-make-sure-my-software-uses-dev-urandom