diff --git a/http-auth.c b/http-auth.c
index 82ae2518..5a9d6b7c 100644
--- a/http-auth.c
+++ b/http-auth.c
@@ -190,6 +190,38 @@ static int basic_authorization(struct openconnect_info *vpninfo, int proxy,
 	return 0;
 }
 
+static int bearer_authorization(struct openconnect_info *vpninfo, int proxy,
+			       struct http_auth_state *auth_state,
+			       struct oc_text_buf *hdrbuf)
+{
+	const char *bearer_token;
+
+	if (proxy) {
+		bearer_token = vpninfo->proxy_bearer_token;
+	} else {
+		bearer_token = vpninfo->bearer_token;
+	}
+
+	if (!bearer_token)
+		return -EINVAL;
+
+	if (auth_state->state == AUTH_IN_PROGRESS) {
+		auth_state->state = AUTH_FAILED;
+		return -EAGAIN;
+	}
+
+	buf_append(hdrbuf, "%sAuthorization: Bearer %s \r\n", proxy ? "Proxy-" : "", bearer_token);
+
+	if (proxy)
+		vpn_progress(vpninfo, PRG_INFO, _("Attempting HTTP Bearer authentication to proxy\n"));
+	else
+		vpn_progress(vpninfo, PRG_INFO, _("Attempting HTTP Bearer authentication to server '%s'\n"),
+			     vpninfo->hostname);
+
+	auth_state->state = AUTH_IN_PROGRESS;
+	return 0;
+}
+
 #if !defined(HAVE_GSSAPI) && !defined(_WIN32)
 static int no_gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 				   struct http_auth_state *auth_state,
@@ -215,6 +247,7 @@ struct auth_method {
 	{ AUTH_TYPE_NTLM, "NTLM", ntlm_authorization, cleanup_ntlm_auth },
 	{ AUTH_TYPE_DIGEST, "Digest", digest_authorization, NULL },
 	{ AUTH_TYPE_BASIC, "Basic", basic_authorization, NULL },
+	{ AUTH_TYPE_BEARER, "Bearer", bearer_authorization, NULL },
 #if !defined(HAVE_GSSAPI) && !defined(_WIN32)
 	{ AUTH_TYPE_GSSAPI, "Negotiate", no_gssapi_authorization, NULL }
 #endif
diff --git a/main.c b/main.c
index 19d64377..602c207d 100644
--- a/main.c
+++ b/main.c
@@ -192,6 +192,7 @@ enum {
 	OPT_PROTOCOL,
 	OPT_PASSTOS,
 	OPT_VERSION,
+	OPT_BEARER_TOKEN,
 };
 
 #ifdef __sun__
@@ -279,6 +280,7 @@ static const struct option long_options[] = {
 #ifdef OPENCONNECT_GNUTLS
 	OPTION("gnutls-debug", 1, OPT_GNUTLS_DEBUG),
 #endif
+	OPTION("bearer-token", 1, OPT_BEARER_TOKEN),
 	OPTION(NULL, 0, 0)
 };
 
@@ -820,6 +822,7 @@ static void usage(void)
 #ifndef HAVE_LIBPCSCLITE
 	printf("                                  %s\n", _("(NOTE: Yubikey OATH disabled in this build)"));
 #endif
+	printf("      --bearer-token=FILE		  %s\n", _("Use HTTP bearer token from file"));
 
 	printf("\n%s:\n", _("Server validation"));
 	printf("      --servercert=FINGERPRINT    %s\n", _("Server's certificate SHA1 fingerprint"));
@@ -1494,6 +1497,9 @@ int main(int argc, char **argv)
 			gnutls_global_set_log_function(oc_gnutls_log_func);
 			break;
 #endif
+		case OPT_BEARER_TOKEN:
+			read_file_into_string(vpninfo, config_arg, &vpninfo->bearer_token);
+			break;
 		default:
 			usage();
 		}
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 30c65848..d9f72337 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -223,8 +223,9 @@ struct oc_text_buf {
 #define AUTH_TYPE_NTLM		1
 #define AUTH_TYPE_DIGEST	2
 #define AUTH_TYPE_BASIC		3
+#define AUTH_TYPE_BEARER	4
 
-#define MAX_AUTH_TYPES		4
+#define MAX_AUTH_TYPES		5
 
 #define AUTH_DEFAULT_DISABLED	-3
 #define AUTH_DISABLED		-2
@@ -419,6 +420,8 @@ struct openconnect_info {
 	int proxy_fd;
 	char *proxy_user;
 	char *proxy_pass;
+	char *bearer_token;
+	char *proxy_bearer_token;
 	int proxy_close_during_auth;
 	int retry_on_auth_fail;
 	int try_http_auth;
