|
|
|
|
@ -1,53 +1,43 @@
|
|
|
|
|
package com.yau.digitalrmb.security.interfaces;
|
|
|
|
|
|
|
|
|
|
import com.yau.digitalrmb.security.application.BootstrapAdminAuthenticator;
|
|
|
|
|
import com.yau.digitalrmb.identity.infrastructure.persistence.entity.PlatformUserSnapshotEntity;
|
|
|
|
|
import com.yau.digitalrmb.identity.infrastructure.persistence.mapper.PlatformUserSnapshotMapper;
|
|
|
|
|
import com.yau.digitalrmb.security.application.JwtTokenService;
|
|
|
|
|
import com.yau.digitalrmb.security.application.LoginExchangeCodeService;
|
|
|
|
|
import com.yau.digitalrmb.security.application.RefreshTokenService;
|
|
|
|
|
import com.yau.digitalrmb.identity.infrastructure.persistence.entity.PlatformUserSnapshotEntity;
|
|
|
|
|
import com.yau.digitalrmb.identity.infrastructure.persistence.mapper.PlatformUserSnapshotMapper;
|
|
|
|
|
import com.yau.digitalrmb.shared.api.ApiResponse;
|
|
|
|
|
import com.yau.digitalrmb.shared.api.ErrorCode;
|
|
|
|
|
import com.yau.digitalrmb.shared.exception.BusinessException;
|
|
|
|
|
import com.yau.digitalrmb.shared.web.TraceIdFilter;
|
|
|
|
|
import jakarta.validation.Valid;
|
|
|
|
|
import org.slf4j.MDC;
|
|
|
|
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|
|
|
|
import org.springframework.security.oauth2.jwt.Jwt;
|
|
|
|
|
import org.springframework.web.bind.annotation.GetMapping;
|
|
|
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
|
@RestController
|
|
|
|
|
@RequestMapping("/api/v1/auth")
|
|
|
|
|
public class AuthController {
|
|
|
|
|
private final BootstrapAdminAuthenticator authenticator;
|
|
|
|
|
private final JwtTokenService tokenService;
|
|
|
|
|
private final LoginExchangeCodeService exchangeCodeService;
|
|
|
|
|
private final RefreshTokenService refreshTokenService;
|
|
|
|
|
private final PlatformUserSnapshotMapper snapshotMapper;
|
|
|
|
|
|
|
|
|
|
public AuthController(BootstrapAdminAuthenticator authenticator, JwtTokenService tokenService,
|
|
|
|
|
LoginExchangeCodeService exchangeCodeService, RefreshTokenService refreshTokenService,
|
|
|
|
|
PlatformUserSnapshotMapper snapshotMapper) {
|
|
|
|
|
this.authenticator = authenticator;
|
|
|
|
|
public AuthController(JwtTokenService tokenService, LoginExchangeCodeService exchangeCodeService,
|
|
|
|
|
RefreshTokenService refreshTokenService, PlatformUserSnapshotMapper snapshotMapper) {
|
|
|
|
|
this.tokenService = tokenService;
|
|
|
|
|
this.exchangeCodeService = exchangeCodeService;
|
|
|
|
|
this.refreshTokenService = refreshTokenService;
|
|
|
|
|
this.snapshotMapper = snapshotMapper;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@PostMapping("/login")
|
|
|
|
|
public ApiResponse<LoginResponse> login(@Valid @RequestBody LoginRequest request) {
|
|
|
|
|
if (!authenticator.matches(request.username(), request.password())) {
|
|
|
|
|
throw new BusinessException(ErrorCode.UNAUTHORIZED, "用户名或密码错误");
|
|
|
|
|
}
|
|
|
|
|
JwtTokenService.Token token = tokenService.issueFor(request.username());
|
|
|
|
|
return ApiResponse.success(new LoginResponse(token.accessToken(), "Bearer", token.expiresIn()),
|
|
|
|
|
MDC.get(TraceIdFilter.MDC_KEY));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@PostMapping("/session/exchange")
|
|
|
|
|
public ApiResponse<SessionResponse> exchange(@Valid @RequestBody ExchangeCodeRequest request) {
|
|
|
|
|
long platformUserId = exchangeCodeService.exchange(request.code());
|
|
|
|
|
@ -61,4 +51,29 @@ public class AuthController {
|
|
|
|
|
return ApiResponse.success(new SessionResponse(accessToken.accessToken(), refreshToken, "Bearer", accessToken.expiresIn()),
|
|
|
|
|
MDC.get(TraceIdFilter.MDC_KEY));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@GetMapping("/me")
|
|
|
|
|
public ApiResponse<CurrentUserResponse> currentUser(@AuthenticationPrincipal Jwt jwt) {
|
|
|
|
|
long platformUserId = platformUserId(jwt);
|
|
|
|
|
PlatformUserSnapshotEntity snapshot = snapshotMapper.selectById(platformUserId);
|
|
|
|
|
if (snapshot == null) {
|
|
|
|
|
throw new BusinessException(ErrorCode.UNAUTHORIZED, "用户身份不存在");
|
|
|
|
|
}
|
|
|
|
|
return ApiResponse.success(new CurrentUserResponse(platformUserId, snapshot.getAccount(), snapshot.getDisplayName(),
|
|
|
|
|
List.of(snapshot.getRoleKey())), MDC.get(TraceIdFilter.MDC_KEY));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@PostMapping("/logout")
|
|
|
|
|
public ApiResponse<Void> logout(@AuthenticationPrincipal Jwt jwt, @Valid @RequestBody LogoutRequest request) {
|
|
|
|
|
refreshTokenService.revokeForUser(request.refreshToken(), platformUserId(jwt));
|
|
|
|
|
return ApiResponse.success(null, MDC.get(TraceIdFilter.MDC_KEY));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long platformUserId(Jwt jwt) {
|
|
|
|
|
try {
|
|
|
|
|
return Long.parseLong(jwt.getSubject());
|
|
|
|
|
} catch (NumberFormatException exception) {
|
|
|
|
|
throw new BusinessException(ErrorCode.UNAUTHORIZED, "用户身份无效");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|