Я хочу протестировать репликацию сеанса в кластерной среде, поэтому я использую Spring Boot + Spring Security + Spring HTTP Session с JDB C. Чтобы включить кластерную среду локально, у меня есть настроенный Apache HTTP-сервер и 3 tomcat
Я замечаю, что всякий раз, когда пользователь входит в систему, данные сеанса пользователя вставляются в таблицы SPRING_SESSION и SPRING_SESSION_ATTTRIBUTE. отправлялись на разные серверы. Запросы не отправлялись на один и тот же сервер. Мое предположение исходит из одного и того же браузера, если я нажимаю запросы, тогда все запросы должны go на один и тот же сервер. но этого не происходит. Я включил sticky_session в worker.properties, чтобы все запросы go приходили на один и тот же сервер.
Я хочу проверить еще одну вещь: если вы видите метод домашней страницы (LoginController), я получаю данные пользователя всякий раз, когда пользователь входит в систему на одном сервере, если этот сервер g Если нижеприведенная конфигурация обслуживает запросы, данные о пользователе будут перемещены на другой сервер?
worker.list=balancer,status
worker.tomcat1.type=ajp13
worker.tomcat1.port=8009
worker.tomcat1.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.port=8010
worker.tomcat2.host=localhost
worker.tomcat3.type=ajp13
worker.tomcat3.port=8011
worker.tomcat3.host=localhost
# status worker
worker.jkstatus.type=status
worker.balancer.sticky_session=true
worker.balancer.type=lb
worker.balancer.balance_workers=tomcat1,tomcat2,tomcat3
spring.datasource.url=jdbc:oracle:thin:@XXXXXXX:1521:XXX
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
#spring.jpa.show-sql=true
#spring.jpa.properties.hibernate.format_sql=true
spring.datasource.username=XXX
spring.datasource.password=XXXX
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.Oracle10gDialect
#logging.level.org.hibernate.SQL=DEBUG
#logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
# ====================================================================================
# = Session Configuration
spring.session.store-type=jdbc
#spring.session.jdbc.initialize-schema=always
spring.session.timeout.seconds=600
spring.h2.console.enabled=true
@SpringBootApplication
@EnableJdbcHttpSession
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public static final Logger LOGGER = LogManager.getLogger(SecurityConfig.class);
@Autowired
private SimpleAuthenticationSuccessHandler loginSuccess;
@Autowired
private LogoutSuccess logoutSuccess;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
LOGGER.info(" Enter >> configureGlobal() ");
auth.jdbcAuthentication()
.usersByUsernameQuery("select email,password_hash,enabled from users where email=?")
.authoritiesByUsernameQuery("select u.email,r.role from users u inner join user_role ur on(u.id=ur.user_id) inner join role r on(r.id=ur.role_id) where u.email=?")
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
LOGGER.info(" Exit << configureGlobal() ");
}
/**
* Handle Login - Authentication and Redirection
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/home")
.hasAuthority("ADMIN")
.antMatchers("/users")
.hasAnyAuthority("USER", "ADMIN")
.and()
.formLogin()
.loginPage("/login")
.successHandler(loginSuccess)
.permitAll()
.and()
.logout()
.logoutSuccessHandler(logoutSuccess)
.deleteCookies("JSESSIONID")
.invalidateHttpSession(false)
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf().disable();
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
final CorsConfiguration config=new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedHeader("*");
config.addAllowedOrigin("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("POST");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter((CorsConfigurationSource) source);
}
}
@Controller
public class LoginController {
@RequestMapping(value = { "/login" })
public String login() {
LOGGER.info("in login controller");
return "login";
}
@RequestMapping(value = "/home", method = RequestMethod.GET)
public String homepage(Model model) {
LOGGER.info(" Enter >> homepage()********************* ");
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
String name = auth.getName();
LOGGER.info(" Enter >> homepage()*********************** "+name);
User user = userManager.findUserByEmail(name);
model.addAttribute("name", user.getFirstname());
LOGGER.info(" Exit << homepage()************************ ");
return "index";
}
}