Implementation of refresh token.

This commit is contained in:
Florian THIERRY
2023-12-01 11:37:04 +01:00
parent 4a7b0b2daf
commit 367676f6d8
22 changed files with 305 additions and 93 deletions

View File

@@ -17,8 +17,8 @@ public class JwtService {
private final int tokenExpirationDelayInMinutes;
public JwtService(
@Value("${application.security.secretKey}") String secretKey,
@Value("${application.security.tokenExpirationDelayInMinutes}") int tokenExpirationDelayInMinutes
@Value("${application.security.jwt.secretKey}") String secretKey,
@Value("${application.security.jwt.expirationDelayInMinutes}") int tokenExpirationDelayInMinutes
) {
algorithm = Algorithm.HMAC512(secretKey);
this.tokenExpirationDelayInMinutes = tokenExpirationDelayInMinutes;

View File

@@ -1,5 +1,6 @@
package org.sportshub.application.user;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -8,29 +9,41 @@ import org.sportshub.application.security.AuthenticationFacade;
import org.sportshub.application.security.JwtService;
import org.sportshub.application.security.annotation.AllowedToAdmins;
import org.sportshub.domain.exception.LoginFailureException;
import org.sportshub.domain.exception.RefreshTokenDoesNotExistException;
import org.sportshub.domain.exception.RefreshTokenExpiredException;
import org.sportshub.domain.exception.UserDoesNotExistException;
import org.sportshub.domain.user.model.RefreshToken;
import org.sportshub.domain.user.model.User;
import org.sportshub.domain.user.model.UserAuthenticationData;
import org.sportshub.domain.user.port.UserPort;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserUseCases {
private static final String TOKEN_TYPE = "Bearer";
private final PasswordEncoder passwordEncoder;
private final JwtService jwtService;
private final UserPort userPort;
private final AuthenticationFacade authenticationFacade;
private final int refreshTokenExpirationDelayInDays;
public UserUseCases(
AuthenticationFacade authenticationFacade,
JwtService jwtService,
PasswordEncoder passwordEncoder,
UserPort userPort
UserPort userPort,
@Value("${application.security.refreshToken.expirationDelayInDays}")
int refreshTokenExpirationDelayInDays
) {
this.passwordEncoder = passwordEncoder;
this.jwtService = jwtService;
this.userPort = userPort;
this.authenticationFacade = authenticationFacade;
this.refreshTokenExpirationDelayInDays = refreshTokenExpirationDelayInDays;
}
public Optional<User> findById(UUID userId) {
@@ -42,11 +55,26 @@ public class UserUseCases {
return userPort.findAll();
}
public String authenticate(final UUID id, final String password) {
return userPort.findById(id)
.filter(user -> passwordEncoder.matches(password, user.password()))
.map(jwtService::createJwt)
public UserAuthenticationData authenticate(UUID userId, String password) {
User user = userPort.findById(userId)
.orElseThrow(LoginFailureException::new);
if (!passwordEncoder.matches(password, user.password())) {
throw new LoginFailureException();
}
return generateAuthenticationData(user);
}
public UserAuthenticationData authenticate(UUID refreshTokenValue) {
RefreshToken refreshToken = userPort.findRefreshTokenById(refreshTokenValue)
.filter(RefreshToken::isNotExpired)
.orElseThrow(() -> new RefreshTokenDoesNotExistException(refreshTokenValue));
User user = userPort.findById(refreshToken.userId())
.orElseThrow(() -> new UserDoesNotExistException(refreshToken.userId()));
return generateAuthenticationData(user);
}
public Optional<User> getAuthenticatedUser() {
@@ -57,4 +85,25 @@ public class UserUseCases {
.map(UUID::fromString)
.flatMap(userPort::findById);
}
private UserAuthenticationData generateAuthenticationData(final User user) {
String accessToken = jwtService.createJwt(user);
RefreshToken newRefreshToken = createNewRefreshToken(user);
return new UserAuthenticationData(
TOKEN_TYPE,
accessToken,
newRefreshToken
);
}
private RefreshToken createNewRefreshToken(User user) {
RefreshToken refreshToken = new RefreshToken(
user.id(),
ZonedDateTime.now().plusDays(refreshTokenExpirationDelayInDays)
);
userPort.save(refreshToken);
return refreshToken;
}
}