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
我正在使用具有 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