oauth fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2026-02-16 18:49:08 +05:30
parent 4853453930
commit a9c0215f4b
2 changed files with 34 additions and 37 deletions

View File

@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@ -36,6 +37,10 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.cloudstack.veeam.VeeamControlService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class BearerOrBasicAuthFilter implements Filter {
// Keep these aligned with SsoService (move to ConfigKeys later)
@ -43,6 +48,8 @@ public class BearerOrBasicAuthFilter implements Filter {
public static final String ISSUER = "veeam-control";
public static final String HMAC_SECRET = "change-this-super-secret-key-change-this";
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
@Override public void init(FilterConfig filterConfig) {}
@Override public void destroy() {}
@ -136,20 +143,35 @@ public class BearerOrBasicAuthFilter implements Filter {
if (!constantTimeEquals(expectedSig, providedSig)) return false;
final String payloadJson;
Map<String, Object> payloadMap;
try {
payloadJson = new String(Base64.getUrlDecoder().decode(payloadB64), StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
String payloadJson = new String(Base64.getUrlDecoder().decode(payloadB64), StandardCharsets.UTF_8);
payloadMap = JSON_MAPPER.readValue(
payloadJson,
new TypeReference<>() {}
);
} catch (IllegalArgumentException | JsonProcessingException e) {
return false;
}
// Super small claims extraction (good enough for our minting format)
final String iss = JsonMini.getString(payloadJson, "iss");
final String scope = JsonMini.getString(payloadJson, "scope");
final Long exp = JsonMini.getLong(payloadJson, "exp");
final String iss = (String)payloadMap.get("iss");
final String scope = (String)payloadMap.get("scope");
final Object expObj = payloadMap.get("exp");
Long exp = null;
if (expObj instanceof Number) {
exp = ((Number) expObj).longValue();
} else if (expObj instanceof String) {
try {
exp = Long.parseLong((String) expObj);
} catch (NumberFormatException ignored) {}
}
if (!ISSUER.equals(iss)) return false;
if (exp == null || Instant.now().getEpochSecond() >= exp) return false;
if (!ISSUER.equals(iss)) {
return false;
}
if (exp == null || Instant.now().getEpochSecond() >= exp) {
return false;
}
return scope != null && hasRequiredScopes(scope);
}
@ -216,32 +238,4 @@ public class BearerOrBasicAuthFilter implements Filter {
for (int i = 0; i < x.length; i++) r |= x[i] ^ y[i];
return r == 0;
}
// Tiny JSON extractor for flat string/number claims. Good enough for tokens you mint.
static final class JsonMini {
static String getString(String json, String key) {
final String needle = "\"" + key + "\":";
int i = json.indexOf(needle);
if (i < 0) return null;
i += needle.length();
while (i < json.length() && Character.isWhitespace(json.charAt(i))) i++;
if (i >= json.length() || json.charAt(i) != '"') return null;
i++;
int j = json.indexOf('"', i);
if (j < 0) return null;
return json.substring(i, j);
}
static Long getLong(String json, String key) {
final String needle = "\"" + key + "\":";
int i = json.indexOf(needle);
if (i < 0) return null;
i += needle.length();
while (i < json.length() && Character.isWhitespace(json.charAt(i))) i++;
int j = i;
while (j < json.length() && (Character.isDigit(json.charAt(j)))) j++;
if (j == i) return null;
return Long.parseLong(json.substring(i, j));
}
}
}

View File

@ -101,6 +101,8 @@ public class SsoService extends ManagerBase implements RouteHandler {
final String effectiveScope = (scope == null) ? "ovirt-app-api" : scope;
final long ttl = DEFAULT_TTL_SECONDS;
long nowMillis = Instant.now().toEpochMilli();
long expMillis = nowMillis + ttl * 1000L;
final String token;
try {
token = JwtUtil.issueHs256Jwt(BearerOrBasicAuthFilter.ISSUER, username, effectiveScope, ttl,
@ -115,6 +117,7 @@ public class SsoService extends ManagerBase implements RouteHandler {
payload.put("access_token", token);
payload.put("token_type", "bearer");
payload.put("expires_in", ttl);
payload.put("exp", expMillis);
payload.put("scope", effectiveScope);
io.getWriter().write(resp, HttpServletResponse.SC_OK, payload, outFormat);