auth
All checks were successful
Build Org Backend / build (push) Successful in 12s

This commit is contained in:
2026-05-09 00:36:49 +01:00
parent c8937357e5
commit aa31cc37d9
7 changed files with 36 additions and 83 deletions

View File

@@ -4,7 +4,6 @@ package org.zaine.app.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.zaine.app.security.JwtUtil;
import org.zaine.app.security.RequiresAuth;
import org.zaine.app.user.User;
import org.zaine.app.user.UserRepository;
import org.springframework.http.*;
@@ -17,7 +16,6 @@ import java.util.Map;
@RestController
@RequestMapping("/api/auth")
@RequiresAuth
@Tag(name = "Authentication")
public class AuthController {

View File

@@ -22,6 +22,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/comments")
@RequiresAuth
@Tag(name = "Comments", description = "Endpoints for managing comments")
public class CommentsController {
@@ -86,7 +87,6 @@ public class CommentsController {
value = "",
consumes = "application/json"
)
@RequiresAuth
public void addComment(@RequestBody CreateCommentDTO dto) {
if (dto.getContent() == null || dto.getContent().trim().isEmpty()) {

View File

@@ -1,31 +0,0 @@
package org.zaine.app.security;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ApiKeyAuthService {
private final String apiKey;
public ApiKeyAuthService(@Value("${org.auth.api-key:}") String apiKey) {
this.apiKey = apiKey == null ? "" : apiKey.trim();
}
public boolean isConfigured() {
return !apiKey.isBlank();
}
public boolean isValid(String candidate) {
if (!isConfigured() || candidate == null || candidate.isBlank()) {
return false;
}
byte[] expected = apiKey.getBytes(StandardCharsets.UTF_8);
byte[] provided = candidate.trim().getBytes(StandardCharsets.UTF_8);
return MessageDigest.isEqual(expected, provided);
}
}

View File

@@ -19,14 +19,11 @@ import java.util.List;
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
public static final String API_KEY_HEADER = "X-Org-Api-Key";
private final ApiKeyAuthService apiKeyAuthService;
private final JwtUtil jwtUtil;
private final RequestMappingHandlerMapping requestMappingHandlerMapping;
public JwtAuthFilter(ApiKeyAuthService apiKeyAuthService,
RequestMappingHandlerMapping requestMappingHandlerMapping) {
this.apiKeyAuthService = apiKeyAuthService;
public JwtAuthFilter(JwtUtil jwtUtil, RequestMappingHandlerMapping requestMappingHandlerMapping) {
this.jwtUtil = jwtUtil;
this.requestMappingHandlerMapping = requestMappingHandlerMapping;
}
@@ -39,17 +36,26 @@ public class JwtAuthFilter extends OncePerRequestFilter {
return;
}
String apiKey = request.getHeader(API_KEY_HEADER);
if (apiKeyAuthService.isValid(apiKey)) {
var auth = new UsernamePasswordAuthenticationToken("api-key", null, List.of());
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(auth);
filterChain.doFilter(request, response);
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing or invalid Authorization header");
return;
}
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Missing or invalid " + API_KEY_HEADER + " header");
String token = authHeader.substring(7);
if (!jwtUtil.isTokenValid(token)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid or expired token");
return;
}
String username = jwtUtil.extractUsername(token);
var auth = new UsernamePasswordAuthenticationToken(username, null, List.of());
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(auth);
filterChain.doFilter(request, response);
}
private boolean endpointRequiresAuth(HttpServletRequest request) {