2017-04-02 108 views
0

我正在創建一個登錄頁面使用彈簧安全春天web mvc。當我在本地機器上部署應用程序時,它按預期工作。登錄頁面加載沒有問題。但是當我嘗試在託管提供程序中部署應用程序時,登錄頁面在最終加載成功之前花了很長時間才能加載。春季網絡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. 

我使用彈簧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 SSD和3TB

頁面成功加載後,如果我刷新它,頁面不再需要很長時間加載。但如果我更改application.properties中的server.port並重新啓動應用程序(再次按Ctrl + C和java -jar),則會再次發生同樣的情況。

我不明白是什麼使託管機器的加載時間花了很長時間,如果與我的本地機器相比。 任何指針應該做什麼或檢查將是非常有幫助

回答

1

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

+0

嗨@羅曼,感謝您的解釋 這個'-Djava.security.egd = file:/ dev /./ urandom'做了詭計,謝謝! 我想我會堅持使用它之前更改任何服務器端。不過,我想知道是否可以從代碼方面做任何事情 –