diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java
index ead30e3d39..1a929b06b8 100644
--- a/app/src/processing/app/Preferences.java
+++ b/app/src/processing/app/Preferences.java
@@ -25,6 +25,8 @@
 import java.awt.Font;
 import java.awt.SystemColor;
 import java.io.*;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
 import java.util.*;
 
 import processing.app.ui.Toolkit;
@@ -123,9 +125,7 @@ static public void init() {
     // http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
     // Less readable version with the Oracle style sheet:
     // http://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
-    handleProxy("http", "http.proxyHost", "http.proxyPort");
-    handleProxy("https", "https.proxyHost", "https.proxyPort");
-    handleProxy("socks", "socksProxyHost", "socksProxyPort");
+    handleProxy();
   }
 
 
@@ -137,15 +137,47 @@ static public void skipInit() {
   }
 
 
-  static void handleProxy(String protocol, String hostProp, String portProp) {
-    String proxyHost = get("proxy." + protocol + ".host");
-    String proxyPort = get("proxy." + protocol + ".port");
-    if (proxyHost != null && proxyHost.length() != 0 &&
-        proxyPort != null && proxyPort.length() != 0) {
-      System.setProperty(hostProp, proxyHost);
-      System.setProperty(portProp, proxyPort);
+  static void handleProxy() {
+    String proxyType = get("proxy.type");
+    String proxyHost = get("proxy.host");
+    String proxyPort = get("proxy.port");
+    if (proxyType == null || proxyType.length() == 0 ||
+        proxyHost == null || proxyHost.length() == 0 ||
+        proxyPort == null || proxyPort.length() == 0) {
+      return;
     }
 
+    switch (proxyType.toLowerCase()) {
+      case "http":
+        System.setProperty("http.proxyHost", proxyHost);
+        System.setProperty("http.proxyPort", proxyPort);
+        break;
+      case "https":
+        System.setProperty("https.proxyHost", proxyHost);
+        System.setProperty("https.proxyPort", proxyPort);
+        break;
+      case "socks":
+        System.setProperty("socksProxyHost", proxyHost);
+        System.setProperty("socksProxyPort", proxyPort);
+        break;
+      default:
+        Messages.showWarning(
+          "Proxy failed to initialize",
+          "Invalid proxy type. Can be either \"http\", \"https\"or \"socks\".");
+    }
+    String proxyUser = get("proxy.user");
+    String proxyPasswd = get("proxy.passwd");
+    if (proxyUser != null && proxyPasswd != null) {
+      Authenticator.setDefault(new Authenticator() {
+        @Override
+        protected PasswordAuthentication getPasswordAuthentication() {
+          if (getRequestingHost().equalsIgnoreCase(proxyHost)) {
+            return new PasswordAuthentication(proxyUser, proxyPasswd.toCharArray());
+          }
+          return null;
+        }
+      });
+    }
   }
 
 
diff --git a/build/shared/lib/defaults.txt b/build/shared/lib/defaults.txt
index 7ba2250d76..cfd19f557c 100644
--- a/build/shared/lib/defaults.txt
+++ b/build/shared/lib/defaults.txt
@@ -313,15 +313,19 @@ run.present.stop.color = #cccccc
 # checker and the contrib manager to run properly in those environments.
 # This changed from proxy.host and proxy.port to proxy.http.host and
 # proxy.http.port in 3.0a8. In addition, https and socks were added.
-proxy.http.host=
-proxy.http.port=
-proxy.https.host=
-proxy.https.port=
-proxy.socks.host=
-proxy.socks.port=
+# This changed back to proxy.host and proxy.port in 4.0b4 because
+# you don't need multiple proxies.
+# The proxy type can be either "http", "https" or "socks".
+proxy.type=
+proxy.host=
+proxy.port=
+proxy.user=
+proxy.passwd=
 # Example of usage (replace 'http' with 'https' or 'socks' as needed)
-#proxy.http.host=proxy.example.com
-#proxy.http.port=8080
+#proxy.type=http
+#proxy.host=proxy.example.com
+#proxy.port=8080
+
 # Whether to use the system proxy by default
 proxy.system=true