wip
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
package com.ddf.vodsystem;
|
||||
|
||||
import com.ddf.vodsystem.dto.properties.AuthProperties;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@EnableAsync
|
||||
@EnableConfigurationProperties(AuthProperties.class)
|
||||
public class VodSystemApplication {
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Optional;
|
||||
public class UserController {
|
||||
private final UserService userService;
|
||||
|
||||
@Value("${jwt.expiration}")
|
||||
@Value("${app.security.expiration.jwt}")
|
||||
private long jwtExpiration;
|
||||
private static final String SUCCESS = "success";
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.ddf.vodsystem.dto.properties;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Validated
|
||||
@ConfigurationProperties(prefix = "app.security")
|
||||
public record AuthProperties (
|
||||
@NotBlank @Size(min = 32) String jwtSecret,
|
||||
@Valid @NotNull Expiration expiration
|
||||
) {
|
||||
public record Expiration (
|
||||
@NotNull Duration jwt,
|
||||
@NotNull Duration refreshToken,
|
||||
@NotNull Duration tokenFamily
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ddf.vodsystem.security;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.gson.GsonFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@Configuration
|
||||
public class GoogleAuthConfig {
|
||||
|
||||
/**
|
||||
* Provides the verifier used to validate Google ID tokens issued for this application's client ID.
|
||||
*
|
||||
* @param googleClientId the OAuth client ID that tokens must be issued for
|
||||
* @return the configured {@link GoogleIdTokenVerifier}
|
||||
*/
|
||||
@Bean
|
||||
public GoogleIdTokenVerifier googleIdTokenVerifier(
|
||||
@Value("${spring.security.oauth2.client.registration.google.client-id}") String googleClientId) {
|
||||
return new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new GsonFactory())
|
||||
.setAudience(Collections.singletonList(googleClientId))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.exceptions.TokenExpiredException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.ddf.vodsystem.dto.properties.AuthProperties;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.oauth2.jwt.JwtException;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -20,10 +21,9 @@ public class JwtService {
|
||||
private static final String USER_ID_CLAIM = "userId";
|
||||
private static final String ISSUER = "vodsystem";
|
||||
|
||||
public JwtService(@Value("${jwt.secret.key}") String jwtSecretKey,
|
||||
@Value("${jwt.expiration}") long jwtExpiration) {
|
||||
this.jwtExpiration = jwtExpiration;
|
||||
this.algorithm = Algorithm.HMAC256(jwtSecretKey);
|
||||
public JwtService(AuthProperties props) {
|
||||
this.jwtExpiration = props.expiration().jwt().toMillis();
|
||||
this.algorithm = Algorithm.HMAC256(props.jwtSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ddf.vodsystem.services;
|
||||
|
||||
import com.ddf.vodsystem.dto.TokenPackage;
|
||||
import com.ddf.vodsystem.dto.properties.AuthProperties;
|
||||
import com.ddf.vodsystem.entities.RefreshToken;
|
||||
import com.ddf.vodsystem.entities.TokenFamily;
|
||||
import com.ddf.vodsystem.entities.User;
|
||||
@@ -9,11 +10,7 @@ import com.ddf.vodsystem.repositories.UserRepository;
|
||||
import com.ddf.vodsystem.security.JwtService;
|
||||
import com.ddf.vodsystem.security.TokenService;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.JsonFactory;
|
||||
import com.google.api.client.json.gson.GsonFactory;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
|
||||
@@ -24,7 +21,6 @@ import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -34,11 +30,8 @@ public class UserService {
|
||||
private final UserRepository userRepository;
|
||||
private final JwtService jwtService;
|
||||
|
||||
@Value("token-family.expiration")
|
||||
private long tokenFamilyExpirationMs;
|
||||
|
||||
@Value("refresh-token.expiration")
|
||||
private long refreshTokenExpirationMs;
|
||||
private final long tokenFamilyExpirationMs;
|
||||
private final long refreshTokenExpirationMs;
|
||||
|
||||
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||
private static final int REFRESH_GRACE_PERIOD_SECONDS = 5;
|
||||
@@ -46,18 +39,16 @@ public class UserService {
|
||||
|
||||
public UserService(UserRepository userRepository,
|
||||
JwtService jwtService,
|
||||
@Value("${google.client.id}") String googleClientId,
|
||||
GoogleIdTokenVerifier verifier,
|
||||
AuthProperties props,
|
||||
TokenService tokenService) {
|
||||
this.userRepository = userRepository;
|
||||
|
||||
NetHttpTransport transport = new NetHttpTransport();
|
||||
JsonFactory jsonFactory = new GsonFactory();
|
||||
|
||||
this.verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
|
||||
.setAudience(Collections.singletonList(googleClientId))
|
||||
.build();
|
||||
this.verifier = verifier;
|
||||
this.jwtService = jwtService;
|
||||
this.tokenService = tokenService;
|
||||
|
||||
this.refreshTokenExpirationMs = props.expiration().refreshToken().toMillis();
|
||||
this.tokenFamilyExpirationMs = props.expiration().tokenFamily().toMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,13 +20,13 @@ spring.flyway.locations=classpath:db/migrations
|
||||
spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID}
|
||||
spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_SECRET}
|
||||
spring.security.oauth2.client.registration.google.scope=profile,email
|
||||
jwt.secret.key=${JWT_SECRET_KEY}
|
||||
app.security.jwt-secret=${JWT_SECRET_KEY}
|
||||
# 1 Hour
|
||||
jwt.expiration=3600000
|
||||
app.security.expiration.jwt=3600000
|
||||
# 7 days
|
||||
refresh-token.expiration=604800000
|
||||
app.security.expiration.refresh-token=604800000
|
||||
# 90 days
|
||||
token-family.expiration=7776000000
|
||||
app.security.expiration.token-family=7776000000
|
||||
|
||||
# Frontend
|
||||
frontend.url=${FRONTEND_URL}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ddf.vodsystem.services;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class UserServiceTest {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user