Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

select ext jwt provider #768

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion inc_internal/oidc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define ZITI_SDK_OIDC_H

#include <uv.h>
#include <ziti/ziti_model.h>
#include "tlsuv/http.h"

#ifdef __cplusplus
Expand All @@ -43,7 +44,7 @@ struct oidc_client_s {
void *data;
tlsuv_http_t http;

const struct ziti_jwt_signer_s *signer_cfg;
ziti_jwt_signer signer_cfg;

oidc_auth_mode mode;
oidc_config_cb config_cb;
Expand Down
2 changes: 1 addition & 1 deletion inc_internal/zt_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ int conn_bridge_info(ziti_connection conn, char *buf, size_t buflen);

void process_connect(struct ziti_conn *conn, ziti_session *session);

void ztx_init_external_auth(ziti_context ztx);
void ztx_init_external_auth(ziti_context ztx, const ziti_jwt_signer *signer);

void ztx_auth_state_cb(void *, ziti_auth_state , const void *);

Expand Down
3 changes: 1 addition & 2 deletions library/external_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ static void ext_signers_cb(ziti_jwt_signer_array signers, const ziti_error *err,
free(signers);
}

void ztx_init_external_auth(ziti_context ztx) {
ziti_jwt_signer *oidc_cfg = ztx->config.id.oidc;
void ztx_init_external_auth(ziti_context ztx, const ziti_jwt_signer *oidc_cfg) {
if (oidc_cfg != NULL) {
NEWP(oidc, oidc_client_t);
oidc_client_init(ztx->loop, oidc, oidc_cfg, NULL);
Expand Down
51 changes: 35 additions & 16 deletions library/oidc.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "utils.h"
#include "ziti/errors.h"
#include "ziti/ziti_buffer.h"
#include "ziti/ziti_model.h"
#include "buffer.h"

#define code_len 40
Expand Down Expand Up @@ -154,7 +153,10 @@ int oidc_client_init(uv_loop_t *loop, oidc_client_t *clt,
const ziti_jwt_signer *cfg, tls_context *tls) {
assert(clt != NULL);
assert(cfg != NULL);
assert(cfg->provider_url != NULL);
if (cfg->provider_url == NULL) {
ZITI_LOG(ERROR, "ziti_jwt_signer.provider_url is missing");
return ZITI_INVALID_CONFIG;
}

clt->config = NULL;
clt->tokens = NULL;
Expand All @@ -164,9 +166,8 @@ int oidc_client_init(uv_loop_t *loop, oidc_client_t *clt,
clt->link_cb = NULL;
clt->link_ctx = NULL;

clt->signer_cfg = cfg;

int rc = tlsuv_http_init(loop, &clt->http, clt->signer_cfg->provider_url);
tlsuv_http_init(loop, &clt->http, cfg->provider_url);
int rc = oidc_client_set_cfg(clt, cfg);
if (rc != 0) {
return rc;
}
Expand All @@ -181,9 +182,20 @@ int oidc_client_init(uv_loop_t *loop, oidc_client_t *clt,
}

int oidc_client_set_cfg(oidc_client_t *clt, const ziti_jwt_signer *cfg) {
clt->signer_cfg = cfg;
tlsuv_http_set_url(&clt->http, clt->signer_cfg->provider_url);
return 0;
free_ziti_jwt_signer(&clt->signer_cfg);

if (cfg->provider_url == NULL) {
return ZITI_INVALID_CONFIG;
}

clt->signer_cfg.client_id = cfg->client_id ? strdup(cfg->client_id) : NULL;
clt->signer_cfg.provider_url = strdup(cfg->provider_url);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all the others have a check first, should this also check? cfg->provider_url ? dup : NULL;?

clt->signer_cfg.audience = cfg->audience ? strdup(cfg->audience) : NULL;
const char *scope;
MODEL_LIST_FOREACH(scope, cfg->scopes) {
model_list_append(&clt->signer_cfg.scopes, strdup(scope));
}
return tlsuv_http_set_url(&clt->http, clt->signer_cfg.provider_url);
}

void oidc_client_set_link_cb(oidc_client_t *clt, oidc_ext_link_cb cb, void *ctx) {
Expand Down Expand Up @@ -214,6 +226,9 @@ static void internal_config_cb(oidc_req *req, int status, json_object *resp) {
}
}
}
if (clt->token_cb != NULL) {
oidc_client_start(clt, clt->token_cb);
}
}

if (clt->config_cb) {
Expand Down Expand Up @@ -264,6 +279,7 @@ static void failed_auth_req(auth_req *req, const char *error) {

static void parse_token_cb(tlsuv_http_req_t *r, char *body, ssize_t len) {
auth_req *req = r->data;
assert(req);
int err;
if (len > 0) {
if (req->json_parser) {
Expand Down Expand Up @@ -312,7 +328,7 @@ static void request_token(auth_req *req, const char *auth_code) {
{"code", auth_code},
{"grant_type", "authorization_code"},
{"code_verifier", req->code_verifier},
{"client_id", req->clt->signer_cfg->client_id},
{"client_id", req->clt->signer_cfg.client_id},
{"redirect_uri", default_cb_url},
};
tlsuv_http_req_form(token_req, sizeof(form) / sizeof(form[0]), form);
Expand Down Expand Up @@ -622,28 +638,31 @@ static void start_ext_auth(auth_req *req, const char *ep, int qc, tlsuv_http_pai

int oidc_client_start(oidc_client_t *clt, oidc_token_cb cb) {
clt->token_cb = cb;
if (clt->config == NULL) {
return 0;
}
ZITI_LOG(DEBUG, "requesting authentication code");
auth_req *req = new_auth_req(clt);

string_buf_t *scopes_buf = new_string_buf();
string_buf_append(scopes_buf, default_scope);
const char *s;
MODEL_LIST_FOREACH(s, clt->signer_cfg->scopes) {
MODEL_LIST_FOREACH(s, clt->signer_cfg.scopes) {
string_buf_append(scopes_buf, " ");
string_buf_append(scopes_buf, s);
}

char *scope = string_buf_to_string(scopes_buf, NULL);
const char *path = get_endpoint_path(clt, "authorization_endpoint");
tlsuv_http_pair query[] = {
{"client_id", clt->signer_cfg->client_id},
{"client_id", clt->signer_cfg.client_id},
{"scope", scope},
{"response_type", "code"},
{"redirect_uri", default_cb_url},
{"code_challenge", req->code_challenge},
{"code_challenge_method", "S256"},
{"audience", clt->signer_cfg->audience ?
clt->signer_cfg->audience : "openziti"},
{"audience", clt->signer_cfg.audience ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a method to be able to add additional params to the authorization endpoint? auth0 is funky about this and I think maybe zitadel was too? it'd be nice to be able to supply additional params in some way in case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parameters should have to come from signer config, we can add them when/if controller supports them

clt->signer_cfg.audience : "openziti"},
};

if (clt->mode == oidc_external) {
Expand Down Expand Up @@ -731,6 +750,7 @@ int oidc_client_close(oidc_client_t *clt, oidc_close_cb cb) {
tlsuv_http_close(&clt->http, http_close_cb);
uv_close((uv_handle_t *) clt->timer, (uv_close_cb) free);
clt->timer = NULL;
free_ziti_jwt_signer(&clt->signer_cfg);
return 0;
}

Expand Down Expand Up @@ -792,10 +812,9 @@ static void refresh_time_cb(uv_timer_t *t) {
struct json_object *tok = json_object_object_get(clt->tokens, "refresh_token");
oidc_req *refresh_req = new_oidc_req(clt, refresh_cb, clt);


tlsuv_http_req_t *req = tlsuv_http_req(&clt->http, "POST", path, parse_cb, refresh_req);
tlsuv_http_req_header(req, "Authorization",
get_basic_auth_header(clt->signer_cfg->client_id));
get_basic_auth_header(clt->signer_cfg.client_id));
const char *refresher = json_object_get_string(tok);
if (clt->refresh_grant && strcmp(clt->refresh_grant, TOKEN_EXCHANGE_GRANT) == 0) {
tlsuv_http_req_form(req, 4, (tlsuv_http_pair[]) {
Expand All @@ -806,7 +825,7 @@ static void refresh_time_cb(uv_timer_t *t) {
});
} else {
tlsuv_http_req_form(req, 3, (tlsuv_http_pair[]) {
{"client_id", clt->signer_cfg->client_id},
{"client_id", clt->signer_cfg.client_id},
{"grant_type", "refresh_token"},
{"refresh_token", refresher},
});
Expand Down
13 changes: 8 additions & 5 deletions library/ziti.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,14 +593,17 @@ int ziti_use_ext_jwt_signer(ziti_context ztx, const char *name) {
if (ztx == NULL || name == NULL)
return ZITI_INVALID_STATE;

ziti_jwt_signer *signer = model_map_remove(&ztx->ext_signers, name);
if (ztx->ext_auth) {
ZTX_LOG(WARN, "OIDC is already configured");
return ZITI_INVALID_STATE;
}

const ziti_jwt_signer *signer = model_map_get(&ztx->ext_signers, name);
if (signer == NULL) {
return ZITI_NOT_FOUND;
}

free_ziti_jwt_signer_ptr(ztx->config.id.oidc);
ztx->config.id.oidc = signer;
ztx_init_external_auth(ztx);
ztx_init_external_auth(ztx, signer);
return ZITI_OK;
}

Expand Down Expand Up @@ -1783,7 +1786,7 @@ static void version_pre_auth_cb(const ziti_version *version, const ziti_error *e
}

if (ztx->id_creds.key == NULL) {
ztx_init_external_auth(ztx);
ztx_init_external_auth(ztx, ztx->config.id.oidc);
return;
}

Expand Down
Loading