我正在尝试使用Hazelcast分布式缓存来复制带有Spring Boot&Spring Security的HTTP会话,但无法进行设置(不过,简单的缓存复制工作良好,我已经通过在一个应用程序节点的map中设置一些值并尝试在其他集群节点上获得它来验证了这一点)。
我已经通过网页上的东西,但不幸的是,我无法设置这一点。应用程序在集群中运行时,在一个节点上登录后,我没有在其他节点上获取会话对象(我正在从会话注册表对象中获取会话)。
我已经在gradle构建文件中包含了依赖项:hazelcast版本:'3.12'和hazelcast-all版本:'3.12'。
下面是我到目前为止尝试过的代码配置。
@Bean
public Config hazelCastConfig(){
Config config = new Config();
config.setInstanceName("hazelcast-instance")
.addMapConfig(
new MapConfig()
.setName("hazelcastConfiguration")
.setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
.setEvictionPolicy(EvictionPolicy.LRU)
.setTimeToLiveSeconds(-1));
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(6701).setPortCount(20);
networkConfig.setPortAutoIncrement(true);
JoinConfig join = networkConfig.getJoin();
join.getMulticastConfig().setEnabled(false);
join.getTcpIpConfig()
.addMember("localhost")
.setEnabled(true);
return config;
}
@Bean
public FilterRegistrationBean hazelcastFilter(HazelcastInstance hazelcastInstance) {
FilterRegistrationBean registration = new FilterRegistrationBean(new SpringAwareWebFilter());
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
registration.addUrlPatterns("/*");
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE);
registration.addInitParameter("sticky-session", "false");
registration.addInitParameter("instance-name", hazelcastInstance.getName());
return registration;
}
@Bean
public ServletListenerRegistrationBean<SessionListener> hazelcastSessionListener() {
return new ServletListenerRegistrationBean<SessionListener>(new SessionListener());
}
@SpringBootApplication
(exclude =
{
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
SessionAutoConfiguration.class
}
)
下面是我的SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* Reference of UserDetailsService service class instance.
* @see UserDetailsService
*/
@Autowired
private UserDetailsService userDetailsService;
/**
* Reference of CustomAuthenticationSuccessHandler instance.
* @see CustomAuthenticationSuccessHandler
*/
@Autowired
private CustomAuthenticationSuccessHandler authenticationSuccessHandler;
/**
* Reference of CustomAuthenticationEntryPoint instance.
* @see CustomAuthenticationEntryPoint
*/
@Autowired
private CustomAuthenticationEntryPoint authenticationEntryPoint;
/**
* Reference of CustomAuthenticationFailureHandler instance.
* @see CustomAuthenticationFailureHandler
*/
@Autowired
private CustomAuthenticationFailureHandler authenticationFailureHandler;
/**
* Reference of CustomLogoutSuccessHandler instance.
* @see CustomLogoutSuccessHandler
*/
@Autowired
CustomLogoutSuccessHandler customLogoutSuccessHandler;
/**
* Reference of PasswordEncoder utility instance.
* @see PasswordEncoder
*/
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private SessionRegistry sessionRegistry;
/**
* Method representing security configuration details, provides AuthenticationManager.
*
* @param auth Allows for easily building in memory authentication, LDAP authentication, JDBC based
* authentication, adding {@link UserDetailsService}, and adding
* AuthenticationProviders.
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
/**
* Method returning a bean of AuthenticationManager which is available during application lifecycle.
*
* @return an instance of default AuthenticationManager.
* @throws Exception
*/
@Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
return authenticationManager();
}
/**
* Method returning a bean of {@link ServletContextInitializer} to register {@link EventListener}s in a Servlet
* 3.0+ container.
*
* This bean can be used to register the following types of listener:
* <ul>
* <li>{@link ServletContextAttributeListener}</li>
* <li>{@link ServletRequestListener}</li>
* <li>{@link ServletRequestAttributeListener}</li>
* <li>{@link HttpSessionAttributeListener}</li>
* <li>{@link HttpSessionListener}</li>
* <li>{@link ServletContextListener}</li>
* </ul>
*
* @return ServletListenerRegistrationBean
*/
@Bean
public static ServletListenerRegistrationBean httpSessionEventPublisher() {
return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}
/**
* Method returning a bean of custom authentication filter containing custom success and failure handlers.
* Also sets SessionAuthenticationStrategy in filter.
*
* @return CustomUsernamePasswordAuthenticationFilter
* @see CustomUsernamePasswordAuthenticationFilter
* @throws Exception
*/
@Bean
public CustomUsernamePasswordAuthenticationFilter authenticationFilter() throws Exception {
CustomUsernamePasswordAuthenticationFilter authenticationFilter
= new CustomUsernamePasswordAuthenticationFilter(sessionRegistry);
authenticationFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
authenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler);
authenticationFilter.setRequiresAuthenticationRequestMatcher(
new AntPathRequestMatcher("/api/login", "POST"));
authenticationFilter.setAuthenticationManager(customAuthenticationManager());
authenticationFilter.setSessionAuthenticationStrategy(concurrentSession());
return authenticationFilter;
}
/**
* Method representing configuration/strategy for concurrent sessions.
*
* @return CompositeSessionAuthenticationStrategy A SessionAuthenticationStrategy that accepts multiple
* SessionAuthenticationStrategy implementations to delegate to. Each
* SessionAuthenticationStrategy is invoked in turn.
*/
@Bean
public CompositeSessionAuthenticationStrategy concurrentSession() {
ConcurrentSessionControlAuthenticationStrategy concurrentAuthenticationStrategy =
new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry);
concurrentAuthenticationStrategy.setMaximumSessions(1);
concurrentAuthenticationStrategy.setExceptionIfMaximumExceeded(false);
List<SessionAuthenticationStrategy> delegateStrategies = new ArrayList<>();
delegateStrategies.add(concurrentAuthenticationStrategy);
delegateStrategies.add(new SessionFixationProtectionStrategy());
delegateStrategies.add(new RegisterSessionAuthenticationStrategy(sessionRegistry));
CompositeSessionAuthenticationStrategy authenticationStrategy =
new CompositeSessionAuthenticationStrategy(delegateStrategies);
return authenticationStrategy;
}
/**
* Method returning a bean of ConcurrentSessionFilter which is available during application life-cycle.
*
* @return ConcurrentSessionFilter
*/
@Bean
ConcurrentSessionFilter concurrentSessionFilter() {
CustomConcurrentSessionFilter concurrentSessionFilter = new CustomConcurrentSessionFilter(sessionRegistry);
return concurrentSessionFilter;
}
/**
* Method representing different types of security rules/configuration for the application.
*
* @param http HttpSecurity object to configure HTTP security parameters.
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
http.sessionManagement().sessionAuthenticationStrategy(concurrentSession());
http.addFilterBefore(concurrentSessionFilter(), ConcurrentSessionFilter.class);
http.authorizeRequests()
.antMatchers("/api/secure/org/**",
"/v2/api-docs",
"/configuration/ui",
"/swagger-resources",
"/configuration/security",
"/swagger-ui.html",
"/webjars*//**//**",
"/swagger-resources/configuration/ui").
hasAnyAuthority("ADMIN").anyRequest().fullyAuthenticated()
.antMatchers("/api/secure/dms/**").
hasAnyAuthority("ADMIN","INTERNAL").anyRequest().fullyAuthenticated()
.antMatchers("/api/secure/ext/**","/api/secure/tests/**").
hasAnyAuthority("ADMIN","INTERNAL","EXT").anyRequest().fullyAuthenticated()
.and()
.addFilterBefore(
authenticationFilter(),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new RequestFilter(), BasicAuthenticationFilter.class)
/*.addFilterBefore(new RequestFilter(), BasicAuthenticationFilter.class)
.formLogin().loginPage("/api/login")
.permitAll()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.usernameParameter("email")
.passwordParameter("password")
.and()
.httpBasic().and()*/
.csrf().ignoringAntMatchers("/api/login","/api/auth/**","/api/secure/**")
.csrfTokenRepository(csrfTokenRepository())
.and()
.logout().logoutUrl("/api/logout")
.invalidateHttpSession(false).logoutSuccessHandler(customLogoutSuccessHandler)
.permitAll();
// http.logout().
// logoutUrl("/api/auth/logout").
// logoutSuccessHandler(customLogoutSuccessHandler);
//http.csrf().disable();
}
/**
* Method overriding/representing security configuration/rules to bypasses configured URLs.
*
* @param web WebSecurity object to apply rules.
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/auth/**","/api/application/**","/api/unsecure/**");
}
/**
* This method configure global security.
*
* @param auth AuthenticationManagerBuilder object
* @throws Exception
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
/**
* This method sets CSRF header name in CSRF token repository.
*
* @return CsrfTokenRepository repository object
*/
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
是否有人可以建议我缺少哪一组配置,或者是否有人可以共享示例代码或任何资源,以使我可以正确配置它。
要求只是复制会话,以便其他集群节点知道现有的会话。
提前致谢!!!
请在这里查看我的示例项目:https://github.com/gokhanoner/seajug-demo
它使用Hazelcast作为会话缓存,也使用Spring session,我相信这正是您所需要的&它是一个更简单的设置。
我有一些hazelcast http会话复制特性的问题。 我有些问题: 在同一个tomcat集群中有没有可能有hazelcast封装的应用程序和非hazelcast封装的应用程序? 带有hazelcast的应用程序应该是可分发的?(通过像其他方法一样添加它的web.xml) 部署应用程序的Tomcat不应该在集群中?是否可以在同一tomcat中使用标准tomcat会话复制将其他应用程序群集化? 编
我在Spring Boot应用程序中遵循基于Hazelcast的会话复制文档。 谢谢Aravind
当我介绍hazelcast时,第一次验证是成功的。之后,第一个请求也是成功的。但在那之后 org.springframework.security.web.context.httpsessionSecurityContextRepository找不到会话... 正如我所说,在配置com.hazelcast.web.webfilter进行sesion复制之后,就开始出现这种情况,如下所示: 2017
背景:我在tomcat上部署了一个javaee webapp,它使用基于表单的身份验证。当web服务器接收到登录请求时,它将该请求发送到一个专用的身份验证服务,该服务验证用户登录(用户id和密码)。验证成功后,用户的会话将在web服务器中维护。 问题:我在这里编写了一个简单的webpp源代码,以模拟该场景。成功登录后,当前实例无效,并创建新实例。对于post登录页面的每个请求,都会验证会话。设置一
我试图使用Spring Cloud的Zuul、Eureka和我自己的服务实现微服务架构。我有多个具有UI和服务的服务,每个服务都可以使用x509安全性对用户进行身份验证。现在我想把祖尔放在那些服务机构的前面。由于Zuul无法将客户端证书转发到后端,我认为下一个最好的方法是在Zuul的前门对用户进行身份验证,然后使用Spring会话在后端服务中复制他们的身份验证状态。我遵循了Dave Syer的教程
我使用redisson在运行tomcat V8.5的3个tomcat吊舱中复制spring应用程序的tomcat会话。我还在同一个Kubernetes集群中部署了Redis。下面是我的tomcat context.xml配置 我的redisson配置如下: 当我在所有pod上运行我的应用程序和负载平衡请求时,它会为发送到不同pod的每个请求创建一个新的JSESSIONID cookie 这应该验证