Added 'localAuthBypassEnabled' setting to allow users to opt in to the old method of local authentication at their own risk.

This commit is contained in:
CalDescent 2021-11-14 15:24:15 +00:00
parent f062acfd7c
commit 06e122f303
2 changed files with 27 additions and 4 deletions

View File

@ -1,6 +1,10 @@
package org.qortal.api;
import org.qortal.settings.Settings;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
@ -9,21 +13,35 @@ public abstract class Security {
public static final String API_KEY_HEADER = "X-API-KEY";
public static void checkApiCallAllowed(HttpServletRequest request) {
ApiKey apiKey = Security.getApiKey(request);
// We may want to allow automatic authentication for local requests, if enabled in settings
boolean localAuthBypassEnabled = Settings.getInstance().isLocalAuthBypassEnabled();
if (localAuthBypassEnabled) {
try {
InetAddress remoteAddr = InetAddress.getByName(request.getRemoteAddr());
if (remoteAddr.isLoopbackAddress()) {
// Request originates from loopback address, so allow it
return;
}
} catch (UnknownHostException e) {
// Ignore failure, and fallback to API key authentication
}
}
// Retrieve the API key
ApiKey apiKey = Security.getApiKey(request);
if (!apiKey.generated()) {
// Not generated an API key yet, so disallow sensitive API calls
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.UNAUTHORIZED, "API key not generated");
}
// We require an API key to be passed
String passedApiKey = request.getHeader(API_KEY_HEADER);
if (passedApiKey == null) {
// We require an API key to be passed
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.UNAUTHORIZED, "Missing 'X-API-KEY' header");
}
// The API keys must match
if (!apiKey.equals(passedApiKey)) {
// The API keys must match
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.UNAUTHORIZED, "API key invalid");
}
}

View File

@ -15,7 +15,6 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.transform.stream.StreamSource;
import bsh.This;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.persistence.exceptions.XMLMarshalException;
@ -77,6 +76,8 @@ public class Settings {
private String apiKey = null;
/** Storage location for API key generated by API (Nov 2021 onwards) */
private String apiKeyPath = "";
/** Whether to allow automatic authentication from localhost (loopback) addresses */
private boolean localAuthBypassEnabled = false;
private Boolean apiRestricted;
private boolean apiLoggingEnabled = false;
@ -488,6 +489,10 @@ public class Settings {
return this.apiKeyPath;
}
public boolean isLocalAuthBypassEnabled() {
return this.localAuthBypassEnabled;
}
public boolean isApiLoggingEnabled() {
return this.apiLoggingEnabled;
}