feature google authO2

This commit is contained in:
David 2025-08-19 01:00:00 +02:00
parent e8a74d6edc
commit d807721187
5 changed files with 49 additions and 17 deletions

View File

@ -40,6 +40,17 @@
<artifactId>infrastructure</artifactId> <artifactId>infrastructure</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- Ensure DTOs and SPI are available at runtime for OAuth2 success handler -->
<dependency>
<groupId>com.dh7789dev</groupId>
<artifactId>data</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.dh7789dev</groupId>
<artifactId>spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>

View File

@ -1,10 +1,8 @@
package com.dh7789dev.xpeditis.configuration; package com.dh7789dev.xpeditis.configuration;
import com.dh7789dev.xpeditis.AuthenticationRepository; import com.dh7789dev.xpeditis.AuthenticationRepository;
import com.dh7789dev.xpeditis.CommonUtil;
import com.dh7789dev.xpeditis.UserRepository; import com.dh7789dev.xpeditis.UserRepository;
import com.dh7789dev.xpeditis.dto.app.UserAccount; import com.dh7789dev.xpeditis.dto.app.UserAccount;
import com.dh7789dev.xpeditis.dto.request.AuthenticationRequest;
import com.dh7789dev.xpeditis.dto.response.AuthenticationResponse; import com.dh7789dev.xpeditis.dto.response.AuthenticationResponse;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
@ -35,11 +33,11 @@ public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccess
DefaultOAuth2User oAuth2User = (DefaultOAuth2User) authentication.getPrincipal(); DefaultOAuth2User oAuth2User = (DefaultOAuth2User) authentication.getPrincipal();
String email = (String) oAuth2User.getAttributes().get("email"); String email = (String) oAuth2User.getAttributes().get("email");
String password = CommonUtil.generatePassword(12); String password = "oauth-generated";
// Ensure the user exists, but do not try to re-authenticate with password
UserAccount user = userRepository.findOrCreateOAuthUser(email, oAuth2User.getAttributes(), password); UserAccount user = userRepository.findOrCreateOAuthUser(email, oAuth2User.getAttributes(), password);
AuthenticationResponse authResponse = authenticationRepository.authenticate( AuthenticationResponse authResponse = authenticationRepository.authenticateOAuthByEmail(user.getEmail());
new AuthenticationRequest(user.getEmail(), user.getPassword()));
response.setContentType("application/json"); response.setContentType("application/json");
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");

View File

@ -9,6 +9,7 @@ spring:
scope: scope:
- profile - profile
- email - email
redirect-uri: "http://localhost:8080/login/oauth2/code/{registrationId}"
provider: provider:
google: google:
authorization-uri: https://accounts.google.com/o/oauth2/v2/auth authorization-uri: https://accounts.google.com/o/oauth2/v2/auth
@ -76,4 +77,4 @@ application:
expiration: 604800000 # 7 days expiration: 604800000 # 7 days
server: server:
port: 8083 port: 8080

View File

@ -8,4 +8,7 @@ public interface AuthenticationRepository {
AuthenticationResponse authenticate(AuthenticationRequest request); AuthenticationResponse authenticate(AuthenticationRequest request);
AuthenticationResponse register(RegisterRequest request); AuthenticationResponse register(RegisterRequest request);
// Issue JWT tokens for an already-authenticated OAuth2 user identified by email
AuthenticationResponse authenticateOAuthByEmail(String email);
} }

View File

@ -57,6 +57,25 @@ public class AuthenticationJwtRepository implements AuthenticationRepository {
.setExpiresAt(jwtUtil.extractExpiration(jwtToken)); .setExpiresAt(jwtUtil.extractExpiration(jwtToken));
} }
@Override
public AuthenticationResponse authenticateOAuthByEmail(String email) {
log.info("OAuth2 authenticate by email: {}", email);
var userEntity = userDao.findByUsernameOrEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + email));
var jwtToken = jwtUtil.generateToken(userEntity);
var refreshToken = jwtUtil.generateRefreshToken(userEntity);
revokeAllUserTokens(userEntity);
saveUserToken(userEntity, jwtToken);
return new AuthenticationResponse()
.setAccessToken(jwtToken)
.setRefreshToken(refreshToken)
.setCreatedAt(jwtUtil.extractCreatedAt(jwtToken))
.setExpiresAt(jwtUtil.extractExpiration(jwtToken));
}
@Override @Override
public AuthenticationResponse register(RegisterRequest request) { public AuthenticationResponse register(RegisterRequest request) {
if (userDao.existsByUsername(request.getUsername())) { if (userDao.existsByUsername(request.getUsername())) {