Skip to content

Commit

Permalink
Expire all session after resetting password
Browse files Browse the repository at this point in the history
  • Loading branch information
Nonononoki committed Sep 19, 2021
1 parent 0c66d56 commit 05cc2be
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
36 changes: 36 additions & 0 deletions src/main/java/com/nonononoki/alovoa/config/SecurityConfig.java
@@ -1,16 +1,27 @@
package com.nonononoki.alovoa.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
import org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy;

import com.nonononoki.alovoa.component.AuthFilter;
import com.nonononoki.alovoa.component.AuthProvider;
Expand Down Expand Up @@ -74,6 +85,8 @@ public void configure(HttpSecurity http) throws Exception {
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class).rememberMe()
.rememberMeServices(rememberMeServices()).key(rememberKey);

http.sessionManagement().maximumSessions(10).expiredSessionStrategy(getSessionInformationExpiredStrategy())
.sessionRegistry(sessionRegistry());
http.csrf().ignoringAntMatchers("/donate/received/**");
http.requiresChannel().anyRequest().requiresSecure();
}
Expand All @@ -90,9 +103,32 @@ public AuthFilter authenticationFilter() throws Exception {
filter.setAuthenticationSuccessHandler(successHandler);
filter.setAuthenticationFailureHandler(failureHandler);
filter.setRememberMeServices(rememberMeServices());
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
return filter;
}

// cf.
// https://stackoverflow.com/questions/32463022/sessionregistry-is-empty-when-i-use-concurrentsessioncontrolauthenticationstrate
public SessionAuthenticationStrategy sessionAuthenticationStrategy() {
List<SessionAuthenticationStrategy> stratList = new ArrayList<>();
SessionFixationProtectionStrategy concStrat = new SessionFixationProtectionStrategy();
stratList.add(concStrat);
RegisterSessionAuthenticationStrategy regStrat = new RegisterSessionAuthenticationStrategy(sessionRegistry());
stratList.add(regStrat);
CompositeSessionAuthenticationStrategy compStrat = new CompositeSessionAuthenticationStrategy(stratList);
return compStrat;
}

public SessionInformationExpiredStrategy getSessionInformationExpiredStrategy() {
SessionInformationExpiredStrategy strat = new SimpleRedirectSessionInformationExpiredStrategy("/logout");
return strat;
}

@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}

@Bean
public TokenBasedRememberMeServices rememberMeServices() throws Exception {
return new TokenBasedRememberMeServices(rememberKey, customUserDetailsService);
Expand Down
33 changes: 32 additions & 1 deletion src/main/java/com/nonononoki/alovoa/service/PasswordService.java
Expand Up @@ -3,6 +3,8 @@
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import javax.mail.MessagingException;
import javax.servlet.http.HttpSession;
Expand All @@ -11,7 +13,9 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.stereotype.Service;

import com.nonononoki.alovoa.entity.User;
Expand Down Expand Up @@ -43,6 +47,9 @@ public class PasswordService {
@Autowired
private MailService mailService;

@Autowired
private SessionRegistry sessionRegistry;

@Value("${app.password-token.length}")
private int tokenLength;

Expand Down Expand Up @@ -98,7 +105,31 @@ public void changePasword(PasswordChangeDto dto, HttpSession session) throws Alo
user.setRegisterToken(null);
}

List<Object> principals = sessionRegistry.getAllPrincipals().stream().filter(auth -> {
try {
String email;
if (auth instanceof DefaultOAuth2User) {
DefaultOAuth2User oauth2User = (DefaultOAuth2User) auth;
email = oauth2User.getAttribute("email");
} else {
email = (String) auth;
}
if (user.getEmail().equals(email)) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}).collect(Collectors.toList());

for (Object p : principals) {
sessionRegistry.getAllSessions(p, false).forEach(sessionInfo -> {
sessionInfo.expireNow();
});
}

userRepo.saveAndFlush(user);
session.invalidate();
}
}

0 comments on commit 05cc2be

Please sign in to comment.