107 lines
3.4 KiB
Java
107 lines
3.4 KiB
Java
package dev.dinauer.oidcproxy.session;
|
|
|
|
import dev.dinauer.oidcproxy.JwtUtils;
|
|
import dev.dinauer.oidcproxy.callback.OidcClient;
|
|
import dev.dinauer.oidcproxy.callback.model.TokenResponse;
|
|
import dev.dinauer.oidcproxy.proxy.exception.TokenNotFoundException;
|
|
import io.quarkus.security.UnauthorizedException;
|
|
import io.smallrye.jwt.auth.principal.DefaultJWTParser;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.transaction.Transactional;
|
|
import org.eclipse.microprofile.jwt.JsonWebToken;
|
|
|
|
import java.security.MessageDigest;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.sql.Ref;
|
|
import java.time.Instant;
|
|
import java.time.ZoneOffset;
|
|
import java.time.ZonedDateTime;
|
|
import java.util.Base64;
|
|
|
|
@ApplicationScoped
|
|
public class SessionService
|
|
{
|
|
@Inject
|
|
EncryptUtils encryptUtils;
|
|
|
|
@Inject
|
|
AccessTokenRepository accessTokenRepository;
|
|
|
|
@Inject
|
|
RefreshTokenRepository refreshTokenRepository;
|
|
|
|
@Inject
|
|
OidcClient client;
|
|
|
|
@Transactional
|
|
public void create(String sessionHash, AccessToken accessToken, RefreshToken refreshToken)
|
|
{
|
|
try
|
|
{
|
|
accessTokenRepository.persist(new AccessTokenEntity().setId(sessionHash).setToken(encryptUtils.encrypt(accessToken.getToken())).setExpiresAt(accessToken.getExpiresAt()));
|
|
refreshTokenRepository.persist(new RefreshTokenEntity().setId(sessionHash).setToken(encryptUtils.encrypt(refreshToken.getToken())).setExpiresAt(refreshToken.getExpiresAt()));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Transactional
|
|
public AccessToken provide(String sessionHash) throws TokenNotFoundException
|
|
{
|
|
AccessTokenEntity dbToken = accessTokenRepository.findById(sessionHash);
|
|
if (isValid(dbToken))
|
|
{
|
|
try
|
|
{
|
|
return new AccessToken(encryptUtils.decrypt(dbToken.getToken()), dbToken.getExpiresAt());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
RefreshTokenEntity dbRefreshToken = refreshTokenRepository.findById(sessionHash);
|
|
if (dbRefreshToken != null)
|
|
{
|
|
try
|
|
{
|
|
TokenResponse tokenResponse = client.refreshAccessToken(encryptUtils.decrypt(dbRefreshToken.getToken()));
|
|
renewAccessToken(sessionHash, new AccessToken(tokenResponse.accessToken()));
|
|
return new AccessToken(tokenResponse.accessToken());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new TokenNotFoundException();
|
|
}
|
|
|
|
}
|
|
throw new TokenNotFoundException();
|
|
}
|
|
|
|
@Transactional
|
|
public void remove(String sessionHash)
|
|
{
|
|
accessTokenRepository.deleteById(sessionHash);
|
|
refreshTokenRepository.deleteById(sessionHash);
|
|
}
|
|
|
|
private boolean isValid(AccessTokenEntity token)
|
|
{
|
|
if (token != null)
|
|
{
|
|
return ZonedDateTime.now().isBefore(token.getExpiresAt());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void renewAccessToken(String sessionHash, AccessToken token) throws Exception
|
|
{
|
|
accessTokenRepository.deleteById(sessionHash);
|
|
accessTokenRepository.persist(new AccessTokenEntity().setId(sessionHash).setToken(encryptUtils.encrypt(token.getToken())).setExpiresAt(token.getExpiresAt()));
|
|
|
|
}
|
|
}
|