2 changed files with 76 additions and 4 deletions
@@ -1,17 +1,30 @@
package com.alttd.altitudeweb.controllers.data_from_auth;
import com.nimbusds.jwt.JWT;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.server.ResponseStatusException;
import jakarta.servlet.http.HttpServletRequest;
import java.util.UUID;
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthenticatedUuid {
private final JwtDecoder jwtDecoder;
@Value("${UNSECURED:#{false}}")
private boolean unsecured;
@@ -22,13 +35,68 @@ public class AuthenticatedUuid {
* @throws ResponseStatusException with 401 status if authentication is invalid
*/
public UUID getAuthenticatedUserUuid() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UUID uuidFromAuth = getUuidFromAuthentication();
if (uuidFromAuth != null) {
return uuidFromAuth;
}
return extractUuidFromAuthorizationHeader();
}
if (authentication == null || !(authentication.getPrincipal() instanceof Jwt jwt)) {
private UUID extractUuidFromAuthorizationHeader() {
log.debug("Attempting to extract UUID directly from Authorization header");
try {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
log.error("No request attributes found");
if (unsecured) {
return UUID.fromString("55e46bc3-2a29-4c53-850f-dbd944dc5c5f");
}
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Authentication required");
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "No request attributes found");
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
log.error("No valid Authorization header found");
if (unsecured) {
return UUID.fromString("55e46bc3-2a29-4c53-850f-dbd944dc5c5f");
}
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "No valid Authorization header");
}
String token = authHeader.substring(7);
Jwt jwt = jwtDecoder.decode(token);
String stringUuid = jwt.getSubject();
log.debug("Successfully extracted UUID {} from Authorization header", stringUuid);
return UUID.fromString(stringUuid);
} catch (Exception e) {
if (e instanceof ResponseStatusException responseStatusException) {
log.debug("Rethrowing ResponseStatusException", e);
throw responseStatusException;
}
log.error("Error extracting UUID from Authorization header", e);
if (unsecured) {
return UUID.fromString("55e46bc3-2a29-4c53-850f-dbd944dc5c5f");
}
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Failed to extract UUID from token");
}
}
private UUID getUuidFromAuthentication() {
Authentication authentication = getAuthentication();
if (authentication == null) {
log.error("Authentication is null");
return null;
}
if (!(authentication.getPrincipal() instanceof Jwt jwt)) {
log.error("Authentication principal is not a JWT {}", authentication.getPrincipal() instanceof JWT);
if (unsecured) {
return UUID.fromString("55e46bc3-2a29-4c53-850f-dbd944dc5c5f");
}
return null;
}
String stringUuid = jwt.getSubject();
@@ -39,4 +107,8 @@ public class AuthenticatedUuid {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid UUID format");
}
}
private static Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
}
@@ -21,7 +21,7 @@ public interface VotingPluginUsersMapper {
WeeklyTotal as totalVotesThisWeek,
MonthTotal as totalVotesThisMonth,
AllTimeTotal as totalVotesAllTime
FROM votingplugin.votingplugin_users
FROM votingplugin.VotingPlugin_Users
WHERE uuid = #{uuid}
""")
Optional<VotingStatsRow> getStatsByUuid(@Param("uuid") UUID uuid);