Session not being created after explicitly authenticating user in spring security

I'm currently trying to implement a session based authentication using spring security and have managed to get the registration and email verification functionality working. I want the user to be authenticated after verifying their email and then be redirected to the onboarding page and then to dashboard on completion of onboarding. I have logged the authentication to console to debug and when there isn't any user then I get a console log with the authentication object containing anonymousUser and also a sessionId. But, when I explicitly try to authenticate the user, the authentication object contains all the info about the user such as principal, etc but not sessionId. any help, please? Here is my security config.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

http
.anonymous(t -> t.disable())
.cors(Customizer.withDefaults())
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/health").permitAll()
.anyRequest().authenticated())
.formLogin(form -> form
.loginPage("/login")
.usernameParameter("email")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/dashboard", true)
.permitAll())
.logout(logout -> logout
.logoutUrl("/api/auth/logout")
.logoutSuccessUrl("/login?logoutSuccess=true")
.deleteCookies("JSESSIONID")
.permitAll())
.exceptionHandling(
e -> e.authenticationEntryPoint(new AuthEntryPoint("/login")))
.sessionManagement(s -> s
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.sessionFixation().migrateSession()
.invalidSessionUrl("/login")
.sessionAuthenticationErrorUrl("/login")
.maximumSessions(10)
.maxSessionsPreventsLogin(true)
.expiredUrl("/login"));

return http.build();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

http
.anonymous(t -> t.disable())
.cors(Customizer.withDefaults())
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/health").permitAll()
.anyRequest().authenticated())
.formLogin(form -> form
.loginPage("/login")
.usernameParameter("email")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/dashboard", true)
.permitAll())
.logout(logout -> logout
.logoutUrl("/api/auth/logout")
.logoutSuccessUrl("/login?logoutSuccess=true")
.deleteCookies("JSESSIONID")
.permitAll())
.exceptionHandling(
e -> e.authenticationEntryPoint(new AuthEntryPoint("/login")))
.sessionManagement(s -> s
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.sessionFixation().migrateSession()
.invalidSessionUrl("/login")
.sessionAuthenticationErrorUrl("/login")
.maximumSessions(10)
.maxSessionsPreventsLogin(true)
.expiredUrl("/login"));

return http.build();
}
3 Replies
JavaBot
JavaBot6mo ago
This post has been reserved for your question.
Hey @Milk Packet! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Milk Packet
Milk PacketOP6mo ago
Here is my email verification service
@Transactional
public ResponseEntity<?> verifyEmail(String token) {
try {
Token savedToken = tokenRepository.findByToken(token)
.orElseThrow(() -> new RuntimeException("Invalid token"));

if (LocalDateTime.now().isAfter(savedToken.getExpiresAt())) {
sendVerificationEmail(savedToken.getUser());
throw new RuntimeException(
"Verification token has expired. A new token has been sent to the same email address");
}

User user = userRepository.findById(savedToken.getUser().getId())
.orElseThrow(() -> new RuntimeException("User not found"));

if (user.isEnabled()) {
return new ResponseEntity<>("User is already verified. Redirecting you shortly.", HttpStatus.OK);
}

user.setEnabled(true);
userRepository.save(user);

UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);

logSecurityContext("After email verification");

savedToken.setValidatedAt(LocalDateTime.now());
tokenRepository.save(savedToken);

return new ResponseEntity<>("Hurrah! Email verified successfully :) Redirecting you shortly",
HttpStatus.OK);
} catch (RuntimeException | MessagingException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
}
@Transactional
public ResponseEntity<?> verifyEmail(String token) {
try {
Token savedToken = tokenRepository.findByToken(token)
.orElseThrow(() -> new RuntimeException("Invalid token"));

if (LocalDateTime.now().isAfter(savedToken.getExpiresAt())) {
sendVerificationEmail(savedToken.getUser());
throw new RuntimeException(
"Verification token has expired. A new token has been sent to the same email address");
}

User user = userRepository.findById(savedToken.getUser().getId())
.orElseThrow(() -> new RuntimeException("User not found"));

if (user.isEnabled()) {
return new ResponseEntity<>("User is already verified. Redirecting you shortly.", HttpStatus.OK);
}

user.setEnabled(true);
userRepository.save(user);

UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);

logSecurityContext("After email verification");

savedToken.setValidatedAt(LocalDateTime.now());
tokenRepository.save(savedToken);

return new ResponseEntity<>("Hurrah! Email verified successfully :) Redirecting you shortly",
HttpStatus.OK);
} catch (RuntimeException | MessagingException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
}
any help, please? Here's the logSecurityContext function
private void logSecurityContext(String message) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
System.out.println(message + " - Authentication: " + authentication);
System.out.println(
message + " - Principal: " + authentication.getPrincipal());
System.out.println(
message + " - Authorities: " + authentication.getAuthorities());
} else {
System.out.println(message + " - No Authentication present");
}
}
private void logSecurityContext(String message) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
System.out.println(message + " - Authentication: " + authentication);
System.out.println(
message + " - Principal: " + authentication.getPrincipal());
System.out.println(
message + " - Authorities: " + authentication.getAuthorities());
} else {
System.out.println(message + " - No Authentication present");
}
}
JavaBot
JavaBot6mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server