在Spring Security+ Redis
我使用的是Spring Security 5.6.0,带有春季会话数据REDIS 2.6.0,Spring Boot 2.6.1。
我正在尝试防止同一用户的并发登录。但是它不会记录以前的登录实例。基本上,我可以在两个不同的浏览器中为同一用户举行两个会话。我也想对登录会话进行FIFO行为。
I tried adding following still it allows multiple concurrent user logins.httpSecurity.sessionManagement().maximumSessions(1);
在数据库中,我有所有用户的Max_concurrent_sessions,值1。我什至尝试了类似问题中建议的覆盖标签和等于方法。
我有以下弹簧安全配置的配置,
httpSecurity.httpBasic().disable()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers(configurationService.getWebSecurityProperties().getAllowedUrls()).permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy)
.and()
.formLogin()
.successHandler(customLoginSuccessHandler) //customLoginSuccessHandler implements AuthenticationSuccessHandler
.failureHandler(authenticationFailureHandler) //CustomLoginFailureHandler extends SimpleUrlAuthenticationFailureHandler
.and()
.logout().logoutSuccessHandler(logoutSuccessHandler)
.and()
.addFilterBefore(corsFilter, WebAsyncManagerIntegrationFilter.class)
.addFilterBefore(metadataGeneratorFilter, ChannelProcessingFilter.class)
.csrf().disable();
我的CompoSitesesessionauthenticationstategaty配置具有以下配置,
@Bean
SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new CompositeSessionAuthenticationStrategy(Arrays.asList(
sessionFixationProtectionStrategy(),
customConcurrentSessionControlAuthenticationStrategy,
registerSessionAuthenticationStrategy()
));
}
@Bean
SessionFixationProtectionStrategy sessionFixationProtectionStrategy() {
SessionFixationProtectionStrategy ret = new SessionFixationProtectionStrategy();
ret.setMigrateSessionAttributes(false);
return ret;
}
@Bean
RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(sessionRegistory);
}
condureconcurrentsessessesconcontrolauthenticationstationgy实现如下
@Override
protected int getMaximumSessionsForThisUser(Authentication authentication) {
LOGGER.debug("Custom Concurrent Control Bean called.");
if (authentication != null) {
User user = (User) authentication.getPrincipal();
if (user != null) {
UserLoginBean userLogin = userManagementService.findUserByUsername(user.getUsername());
if (userLogin != null) {
return userLogin.getMaxConcurrentSessions();
}
}
}
return 1;
}
@Override
protected void allowableSessionsExceeded(List<SessionInformation> sessions, int allowableSessions,
SessionRegistry registry) throws SessionAuthenticationException {
super.allowableSessionsExceeded(sessions, allowableSessions, registry);
List<SessionInformation> expiredSessions = extractExpiredSessionInformation(sessions);
if (expiredSessions == null || expiredSessions.isEmpty()) {
return;
}
for (SessionInformation each : expiredSessions) {
registry.removeSessionInformation(each.getSessionId());
}
}
private List<SessionInformation> extractExpiredSessionInformation(List<SessionInformation> sessions) {
if (sessions == null || sessions.isEmpty()) {
return new ArrayList<>();
}
List<SessionInformation> ret = new ArrayList<>();
for (SessionInformation each : sessions) {
if (each.isExpired()) {
ret.add(each);
}
}
return ret;
}
I am using spring security 5.6.0 with spring session data redis 2.6.0, spring boot 2.6.1.
I am trying to prevent concurrent logins for the same user. But it does not logs out the previous login instance. Basically I can have two sessions in two different browsers for the same user. Also I want to have FIFO behaviour for login sessions.
I tried adding following still it allows multiple concurrent user logins.httpSecurity.sessionManagement().maximumSessions(1);
In database I have max_concurrent_sessions with value 1 for all users. I even tried overriding Hashcode and equals method as suggestted in similar questions.
I have following configurations for spring security
httpSecurity.httpBasic().disable()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers(configurationService.getWebSecurityProperties().getAllowedUrls()).permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy)
.and()
.formLogin()
.successHandler(customLoginSuccessHandler) //customLoginSuccessHandler implements AuthenticationSuccessHandler
.failureHandler(authenticationFailureHandler) //CustomLoginFailureHandler extends SimpleUrlAuthenticationFailureHandler
.and()
.logout().logoutSuccessHandler(logoutSuccessHandler)
.and()
.addFilterBefore(corsFilter, WebAsyncManagerIntegrationFilter.class)
.addFilterBefore(metadataGeneratorFilter, ChannelProcessingFilter.class)
.csrf().disable();
I have CompositeSessionAuthenticationStrategy configuration with following configs
@Bean
SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new CompositeSessionAuthenticationStrategy(Arrays.asList(
sessionFixationProtectionStrategy(),
customConcurrentSessionControlAuthenticationStrategy,
registerSessionAuthenticationStrategy()
));
}
@Bean
SessionFixationProtectionStrategy sessionFixationProtectionStrategy() {
SessionFixationProtectionStrategy ret = new SessionFixationProtectionStrategy();
ret.setMigrateSessionAttributes(false);
return ret;
}
@Bean
RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(sessionRegistory);
}
customConcurrentSessionControlAuthenticationStrategy implementation is as follows
@Override
protected int getMaximumSessionsForThisUser(Authentication authentication) {
LOGGER.debug("Custom Concurrent Control Bean called.");
if (authentication != null) {
User user = (User) authentication.getPrincipal();
if (user != null) {
UserLoginBean userLogin = userManagementService.findUserByUsername(user.getUsername());
if (userLogin != null) {
return userLogin.getMaxConcurrentSessions();
}
}
}
return 1;
}
@Override
protected void allowableSessionsExceeded(List<SessionInformation> sessions, int allowableSessions,
SessionRegistry registry) throws SessionAuthenticationException {
super.allowableSessionsExceeded(sessions, allowableSessions, registry);
List<SessionInformation> expiredSessions = extractExpiredSessionInformation(sessions);
if (expiredSessions == null || expiredSessions.isEmpty()) {
return;
}
for (SessionInformation each : expiredSessions) {
registry.removeSessionInformation(each.getSessionId());
}
}
private List<SessionInformation> extractExpiredSessionInformation(List<SessionInformation> sessions) {
if (sessions == null || sessions.isEmpty()) {
return new ArrayList<>();
}
List<SessionInformation> ret = new ArrayList<>();
for (SessionInformation each : sessions) {
if (each.isExpired()) {
ret.add(each);
}
}
return ret;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论