Skip to content

Commit

Permalink
accept bearer tokens in header, post or query param; closes #112
Browse files Browse the repository at this point in the history
  • Loading branch information
Hans Zandbelt committed Jan 14, 2016
1 parent e9fa23a commit be6d600
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 26 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
1/14/2015
- add support for passing in OAuth bearer tokens as one or more of: header, post param or query param (OIDCOAuthAcceptTokenAs)
- bump to 1.8.8rc0

1/8/2015
- release 1.8.7

Expand Down
9 changes: 9 additions & 0 deletions auth_openidc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,15 @@

#OIDCOAuthRemoteUserClaim <claim-name> [<regular-expression>]

# (Optional)
# Define the way(s) in which bearer OAuth tokens can be passed to this Resource Server.
# Must be one or several of:
# "header" : an Authorization: bearer" header
# "post" : an HTTP Post parameter called "access_token"
# "query" : as an HTTP query parameter called "access_token"
# When not defined the default "header" is used.
#OIDCOAuthAcceptTokenAs [header|post|query]+

########################################################################################
#
# (Optional)
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AC_INIT([mod_auth_openidc],[1.8.7],[hzandbelt@pingidentity.com])
AC_INIT([mod_auth_openidc],[1.8.8rc0],[hzandbelt@pingidentity.com])

AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION())

Expand Down
57 changes: 57 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,54 @@ static const char * oidc_set_pass_idtoken_as(cmd_parms *cmd, void *dummy,
return NULL;
}

static int oidc_oauth_accept_token_as_str2int(const char *v) {
if (apr_strnatcmp(v, "header") == 0)
return OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER;
if (apr_strnatcmp(v, "post") == 0)
return OIDC_OAUTH_ACCEPT_TOKEN_IN_POST;
if (apr_strnatcmp(v, "query") == 0)
return OIDC_OAUTH_ACCEPT_TOKEN_IN_QUERY;
return -1;
}

/*
* define which method of pass an OAuth Bearer token is accepted
*/
static const char * oidc_set_accept_oauth_token_in(cmd_parms *cmd, void *m,
const char *v1, const char *v2, const char *v3) {
oidc_dir_cfg *dir_cfg = (oidc_dir_cfg *) m;

int b = oidc_oauth_accept_token_as_str2int(v1);
if (b != -1) {
dir_cfg->oauth_accept_token_in = b;
} else {
return apr_psprintf(cmd->pool, "Invalid value \"%s\" for directive %s",
v1, cmd->directive->directive);
}
if (v2) {
b = oidc_oauth_accept_token_as_str2int(v2);
if (b != -1) {
dir_cfg->oauth_accept_token_in |= b;
} else {
return apr_psprintf(cmd->pool,
"Invalid value \"%s\" for directive %s", v2,
cmd->directive->directive);
}
if (v3) {
b = oidc_oauth_accept_token_as_str2int(v3);
if (b != -1) {
dir_cfg->oauth_accept_token_in |= b;
} else {
return apr_psprintf(cmd->pool,
"Invalid value \"%s\" for directive %s", v3,
cmd->directive->directive);
}
}
}

return NULL;
}

/*
* set the syntax of the token expiry claim in the introspection response
*/
Expand Down Expand Up @@ -1366,6 +1414,7 @@ void *oidc_create_dir_config(apr_pool_t *pool, char *path) {
c->pass_cookies = apr_array_make(pool, 0, sizeof(const char *));
c->pass_info_in_headers = 1;
c->pass_info_in_env_vars = 1;
c->oauth_accept_token_in = OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER;
return (c);
}

Expand Down Expand Up @@ -1399,6 +1448,9 @@ void *oidc_merge_dir_config(apr_pool_t *pool, void *BASE, void *ADD) {
c->pass_info_in_env_vars = (
add->pass_info_in_env_vars != 1 ?
add->pass_info_in_env_vars : base->pass_info_in_env_vars);
c->oauth_accept_token_in = (
add->oauth_accept_token_in != OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER ?
add->oauth_accept_token_in : base->oauth_accept_token_in);
return (c);
}

Expand Down Expand Up @@ -2169,5 +2221,10 @@ const command_rec oidc_config_cmds[] = {
oidc_set_pass_claims_as, NULL,
RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
"Specify how claims are passed to the application(s); must be one of \"none\", \"headers\", \"environment\" or \"both\" (default)."),
AP_INIT_TAKE123("OIDCOAuthAcceptTokenAs",
oidc_set_accept_oauth_token_in,
NULL,
RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
"The method in which an OAuth token can be presented; must be one or more of: header|post|query"),
{ NULL }
};
8 changes: 8 additions & 0 deletions src/mod_auth_openidc.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ APLOG_USE_MODULE(auth_openidc);
/* pass id_token in compact serialized format in header*/
#define OIDC_PASS_IDTOKEN_AS_SERIALIZED 4

/* accept bearer token in header (default) */
#define OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER 1
/* accept bearer token as a post parameter */
#define OIDC_OAUTH_ACCEPT_TOKEN_IN_POST 2
/* accept bearer token as a query parameter */
#define OIDC_OAUTH_ACCEPT_TOKEN_IN_QUERY 4

/* prefix of the cookie that binds the state in the authorization request/response to the browser */
#define OIDCStateCookiePrefix "mod_auth_openidc_state_"

Expand Down Expand Up @@ -346,6 +353,7 @@ typedef struct oidc_dir_cfg {
apr_array_header_t *pass_cookies;
apr_byte_t pass_info_in_headers;
apr_byte_t pass_info_in_env_vars;
apr_byte_t oauth_accept_token_in;
} oidc_dir_cfg;

int oidc_check_user_id(request_rec *r);
Expand Down
71 changes: 46 additions & 25 deletions src/oauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,43 +111,64 @@ static apr_byte_t oidc_oauth_validate_access_token(request_rec *r, oidc_cfg *c,
static apr_byte_t oidc_oauth_get_bearer_token(request_rec *r,
const char **access_token) {

/* get the authorization header */
const char *auth_line;
auth_line = apr_table_get(r->headers_in, "Authorization");
if (auth_line) {
oidc_debug(r, "authorization header found");

/* look for the Bearer keyword */
if (apr_strnatcasecmp(ap_getword(r->pool, &auth_line, ' '), "Bearer")) {
oidc_error(r, "client used unsupported authentication scheme: %s",
r->uri);
return FALSE;
}
/* get a handle to the directory config */
oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
&auth_openidc_module);

/* skip any spaces after the Bearer keyword */
while (apr_isspace(*auth_line)) {
auth_line++;
}
*access_token = NULL;

/* copy the result in to the access_token */
*access_token = apr_pstrdup(r->pool, auth_line);
if (dir_cfg->oauth_accept_token_in & OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER) {

} else {
/* get the authorization header */
const char *auth_line;
auth_line = apr_table_get(r->headers_in, "Authorization");
if (auth_line) {
oidc_debug(r, "authorization header found");

/* look for the Bearer keyword */
if (apr_strnatcasecmp(ap_getword(r->pool, &auth_line, ' '),
"Bearer") == 0) {

/* skip any spaces after the Bearer keyword */
while (apr_isspace(*auth_line)) {
auth_line++;
}

/* copy the result in to the access_token */
*access_token = apr_pstrdup(r->pool, auth_line);

} else {
oidc_warn(r,
"client used unsupported authentication scheme: %s",
r->uri);
}
}
}

if ((*access_token == NULL) && (r->method_number == M_POST)
&& (dir_cfg->oauth_accept_token_in & OIDC_OAUTH_ACCEPT_TOKEN_IN_POST)) {
apr_table_t *params = apr_table_make(r->pool, 8);
oidc_util_read_form_encoded_params(r, params, r->args);
if (oidc_util_read_post_params(r, params) == TRUE) {
*access_token = apr_table_get(params, "access_token");
}
}

if ((*access_token == NULL)
&& (dir_cfg->oauth_accept_token_in
& OIDC_OAUTH_ACCEPT_TOKEN_IN_QUERY)) {
apr_table_t *params = apr_table_make(r->pool, 8);
oidc_util_read_form_encoded_params(r, params, r->args);
*access_token = apr_table_get(params, "access_token");
}

if (*access_token == NULL) {
oidc_debug(r, "no authorization header found and no authorization query parameter found");
return FALSE;
}
if (*access_token == NULL) {
oidc_debug(r,
"no bearer token found in authorization header, post or query parameter");
return FALSE;
}

/* log some stuff */
oidc_debug(r, "bearer token: %s", *access_token);

return TRUE;
}

Expand Down

0 comments on commit be6d600

Please sign in to comment.