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.
This commit is contained in:
Remi Tricot-Le Breton 2021-10-01 15:36:53 +02:00 committed by William Lallemand
parent 1d58b01316
commit f5dd337b12
3 changed files with 57 additions and 4 deletions

View File

@ -20038,6 +20038,13 @@ http_auth(<userlist>) : boolean
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

View File

@ -77,6 +77,7 @@ enum ht_auth_m {
HTTP_AUTH_UNKNOWN = 0,
HTTP_AUTH_BASIC,
HTTP_AUTH_DIGEST,
HTTP_AUTH_BEARER,
} __attribute__((packed));
/* All implemented HTTP status codes */

View File

@ -146,6 +146,9 @@ static int get_http_auth(struct sample *smp, struct htx *htx)
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 @@ static int smp_fetch_http_auth_type(const struct arg *args, struct sample *smp,
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 @@ static int smp_fetch_http_auth_user(const struct arg *args, struct sample *smp,
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 @@ static int smp_fetch_http_auth_pass(const struct arg *args, struct sample *smp,
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 @@ static int smp_fetch_http_auth_pass(const struct arg *args, struct sample *smp,
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 @@ static int smp_fetch_http_auth(const struct arg *args, struct sample *smp, const
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 @@ static int smp_fetch_http_auth_grp(const struct arg *args, struct sample *smp, c
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 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "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 },