MINOR: http: Add http_auth_bearer sample fetch
This fetch can be used to retrieve the data contained in an HTTP
Authorization header when the Bearer scheme is used. This is used when
transmitting JSON Web Tokens for instance.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 621ca2f..5466487 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -20038,6 +20038,13 @@
fetch function is not really useful outside of ACLs. Currently only http
basic auth is supported.
+http_auth_bearer([<header>]) : string
+ Returns the client-provided token found in the authorization data when the
+ Bearer scheme is used (to send JSON Web Tokens for instance). No check is
+ performed on the data sent by the client.
+ If a specific <header> is supplied, it will parse this header instead of the
+ Authorization one.
+
http_auth_group(<userlist>) : string
Returns a string corresponding to the user name found in the authentication
data received from the client if both the user name and password are valid
diff --git a/include/haproxy/http-t.h b/include/haproxy/http-t.h
index c6c50c9..3165082 100644
--- a/include/haproxy/http-t.h
+++ b/include/haproxy/http-t.h
@@ -77,6 +77,7 @@
HTTP_AUTH_UNKNOWN = 0,
HTTP_AUTH_BASIC,
HTTP_AUTH_DIGEST,
+ HTTP_AUTH_BEARER,
} __attribute__((packed));
/* All implemented HTTP status codes */
diff --git a/src/http_fetch.c b/src/http_fetch.c
index d3192aa..7b4e41d 100644
--- a/src/http_fetch.c
+++ b/src/http_fetch.c
@@ -146,6 +146,9 @@
txn->auth.method = HTTP_AUTH_BASIC;
return 1;
+ } else if (!strncasecmp("Bearer", auth_method.area, auth_method.data)) {
+ txn->auth.method = HTTP_AUTH_BEARER;
+ return 1;
}
return 0;
@@ -1291,6 +1294,10 @@
smp->data.u.str.area = "Digest";
smp->data.u.str.data = 6;
break;
+ case HTTP_AUTH_BEARER:
+ smp->data.u.str.area = "Bearer";
+ smp->data.u.str.data = 6;
+ break;
default:
return 0;
}
@@ -1313,7 +1320,7 @@
return 0;
txn = smp->strm->txn;
- if (!get_http_auth(smp, htx))
+ if (!get_http_auth(smp, htx) || txn->auth.method != HTTP_AUTH_BASIC)
return 0;
smp->data.type = SMP_T_STR;
@@ -1336,7 +1343,7 @@
return 0;
txn = smp->strm->txn;
- if (!get_http_auth(smp, htx))
+ if (!get_http_auth(smp, htx) || txn->auth.method != HTTP_AUTH_BASIC)
return 0;
smp->data.type = SMP_T_STR;
@@ -1346,6 +1353,43 @@
return 1;
}
+static int smp_fetch_http_auth_bearer(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ struct channel *chn = SMP_REQ_CHN(smp);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
+ struct http_txn *txn;
+ struct buffer bearer_val = {};
+
+ if (!htx)
+ return 0;
+
+ if (args->type == ARGT_STR) {
+ struct http_hdr_ctx ctx;
+ struct ist hdr_name = ist2(args->data.str.area, args->data.str.data);
+
+ ctx.blk = NULL;
+ if (http_find_header(htx, hdr_name, &ctx, 0)) {
+ char *space = NULL;
+ space = memchr(ctx.value.ptr, ' ', ctx.value.len);
+ if (space && strncasecmp("Bearer", ctx.value.ptr, ctx.value.len) == 0) {
+ chunk_initlen(&bearer_val, space+1, 0, ctx.value.len - (space - ctx.value.ptr) - 1);
+ }
+ }
+ }
+ else {
+ txn = smp->strm->txn;
+ if (!get_http_auth(smp, htx) || txn->auth.method != HTTP_AUTH_BEARER)
+ return 0;
+
+ bearer_val = txn->auth.method_data;
+ }
+
+ smp->data.type = SMP_T_STR;
+ smp->data.u.str = bearer_val;
+ smp->flags = SMP_F_CONST;
+ return 1;
+}
+
/* Accepts exactly 1 argument of type userlist */
static int smp_fetch_http_auth(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
@@ -1357,7 +1401,7 @@
if (!htx)
return 0;
- if (!get_http_auth(smp, htx))
+ if (!get_http_auth(smp, htx) || smp->strm->txn->auth.method != HTTP_AUTH_BASIC)
return 0;
smp->data.type = SMP_T_BOOL;
@@ -1377,7 +1421,7 @@
if (!htx)
return 0;
- if (!get_http_auth(smp, htx))
+ if (!get_http_auth(smp, htx) || smp->strm->txn->auth.method != HTTP_AUTH_BASIC)
return 0;
/* if the user does not belong to the userlist or has a wrong password,
@@ -2097,6 +2141,7 @@
{ "http_auth_type", smp_fetch_http_auth_type, 0, NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "http_auth_user", smp_fetch_http_auth_user, 0, NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "http_auth_pass", smp_fetch_http_auth_pass, 0, NULL, SMP_T_STR, SMP_USE_HRQHV },
+ { "http_auth_bearer", smp_fetch_http_auth_bearer, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "http_auth", smp_fetch_http_auth, ARG1(1,USR), NULL, SMP_T_BOOL, SMP_USE_HRQHV },
{ "http_auth_group", smp_fetch_http_auth_grp, ARG1(1,USR), NULL, SMP_T_STR, SMP_USE_HRQHV },
{ "http_first_req", smp_fetch_http_first_req, 0, NULL, SMP_T_BOOL, SMP_USE_HRQHP },