/* * check if the provided OAuth/OIDC response type is supported */ const char *oidc_valid_response_type(apr_pool_t *pool, const char *arg) { if (oidc_proto_flow_is_supported(pool, arg) == FALSE) { return apr_psprintf(pool, "oidc_valid_response_type: type must be one of %s", apr_array_pstrcat(pool, oidc_proto_supported_flows(pool), '|')); } return NULL; }
/* * check if a particular OpenID Connect flow is supported */ apr_byte_t oidc_proto_flow_is_supported(apr_pool_t *pool, const char *flow) { apr_array_header_t *flows = oidc_proto_supported_flows(pool); int i; for (i = 0; i < flows->nelts; i++) { if (oidc_util_spaced_string_equals(pool, flow, ((const char**) flows->elts)[i])) return TRUE; } return FALSE; }
/* * register the client with the OP using Dynamic Client Registration */ static apr_byte_t oidc_metadata_client_register(request_rec *r, oidc_cfg *cfg, oidc_provider_t *provider, json_t **j_client, const char **response) { /* get a handle to the directory config */ oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config, &auth_openidc_module); /* assemble the JSON registration request */ json_t *data = json_object(); json_object_set_new(data, "client_name", json_string(provider->client_name)); json_object_set_new(data, "redirect_uris", json_pack("[s]", cfg->redirect_uri)); json_t *response_types = json_array(); apr_array_header_t *flows = oidc_proto_supported_flows(r->pool); int i; for (i = 0; i < flows->nelts; i++) { json_array_append_new(response_types, json_string(((const char**) flows->elts)[i])); } json_object_set_new(data, "response_types", response_types); if (provider->client_contact != NULL) { json_object_set_new(data, "contacts", json_pack("[s]", provider->client_contact)); } if (provider->client_jwks_uri) { json_object_set_new(data, "jwks_uri", json_string(provider->client_jwks_uri)); } else if (cfg->public_keys != NULL) { json_object_set_new(data, "jwks_uri", json_string( apr_psprintf(r->pool, "%s?jwks=rsa", cfg->redirect_uri))); } if (provider->id_token_signed_response_alg != NULL) { json_object_set_new(data, "id_token_signed_response_alg", json_string(provider->id_token_signed_response_alg)); } if (provider->id_token_encrypted_response_alg != NULL) { json_object_set_new(data, "id_token_encrypted_response_alg", json_string(provider->id_token_encrypted_response_alg)); } if (provider->id_token_encrypted_response_enc != NULL) { json_object_set_new(data, "id_token_encrypted_response_enc", json_string(provider->id_token_encrypted_response_enc)); } if (provider->userinfo_signed_response_alg != NULL) { json_object_set_new(data, "userinfo_signed_response_alg", json_string(provider->userinfo_signed_response_alg)); } if (provider->userinfo_encrypted_response_alg != NULL) { json_object_set_new(data, "userinfo_encrypted_response_alg", json_string(provider->userinfo_encrypted_response_alg)); } if (provider->userinfo_encrypted_response_enc != NULL) { json_object_set_new(data, "userinfo_encrypted_response_enc", json_string(provider->userinfo_encrypted_response_enc)); } json_object_set_new(data, "initiate_login_uri", json_string(cfg->redirect_uri)); json_object_set_new(data, "logout_uri", json_string( apr_psprintf(r->pool, "%s?logout=%s", cfg->redirect_uri, OIDC_GET_STYLE_LOGOUT_PARAM_VALUE))); if (cfg->default_slo_url != NULL) { json_object_set_new(data, "post_logout_redirect_uris", json_pack("[s]", cfg->default_slo_url)); } if (provider->registration_endpoint_json != NULL) { json_error_t json_error; json_t *json = json_loads(provider->registration_endpoint_json, 0, &json_error); if (json == NULL) { oidc_error(r, "JSON parsing returned an error: %s", json_error.text); } else { if (!json_is_object(json)) { oidc_error(r, "parsed JSON did not contain a JSON object"); } else { const char *key; json_t *value; json_object_foreach(json, key, value) { json_object_set(data, key, value); } } json_decref(json); }
/* * register the client with the OP using Dynamic Client Registration */ static apr_byte_t oidc_metadata_client_register(request_rec *r, oidc_cfg *cfg, oidc_provider_t *provider, json_t **j_client, const char **response) { /* get a handle to the directory config */ oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config, &auth_openidc_module); /* assemble the JSON registration request */ json_t *data = json_object(); json_object_set_new(data, "client_name", json_string(provider->client_name)); json_object_set_new(data, "redirect_uris", json_pack("[s]", cfg->redirect_uri)); json_t *response_types = json_array(); apr_array_header_t *flows = oidc_proto_supported_flows(r->pool); int i; for (i = 0; i < flows->nelts; i++) { json_array_append_new(response_types, json_string(((const char**) flows->elts)[i])); } json_object_set_new(data, "response_types", response_types); if (provider->client_contact != NULL) { json_object_set_new(data, "contacts", json_pack("[s]", provider->client_contact)); } if (provider->client_jwks_uri) { json_object_set_new(data, "jwks_uri", json_string(provider->client_jwks_uri)); } else if (cfg->public_keys != NULL) { json_object_set_new(data, "jwks_uri", json_string( apr_psprintf(r->pool, "%s?jwks=rsa", cfg->redirect_uri))); } if (provider->id_token_signed_response_alg != NULL) { json_object_set_new(data, "id_token_signed_response_alg", json_string(provider->id_token_signed_response_alg)); } if (provider->id_token_encrypted_response_alg != NULL) { json_object_set_new(data, "id_token_encrypted_response_alg", json_string(provider->id_token_encrypted_response_alg)); } if (provider->id_token_encrypted_response_enc != NULL) { json_object_set_new(data, "id_token_encrypted_response_enc", json_string(provider->id_token_encrypted_response_enc)); } if (provider->userinfo_signed_response_alg != NULL) { json_object_set_new(data, "userinfo_signed_response_alg", json_string(provider->userinfo_signed_response_alg)); } if (provider->userinfo_encrypted_response_alg != NULL) { json_object_set_new(data, "userinfo_encrypted_response_alg", json_string(provider->userinfo_encrypted_response_alg)); } if (provider->userinfo_encrypted_response_enc != NULL) { json_object_set_new(data, "userinfo_encrypted_response_enc", json_string(provider->userinfo_encrypted_response_enc)); } json_object_set_new(data, "initiate_login_uri", json_string(cfg->redirect_uri)); json_object_set_new(data, "logout_uri", json_string( apr_psprintf(r->pool, "%s?logout=%s", cfg->redirect_uri, OIDC_GET_STYLE_LOGOUT_PARAM_VALUE))); if (cfg->default_slo_url != NULL) { json_object_set_new(data, "post_logout_redirect_uris", json_pack("[s]", cfg->default_slo_url)); } if (provider->registration_endpoint_json != NULL) { json_error_t json_error; json_t *json = json_loads(provider->registration_endpoint_json, 0, &json_error); if (json == NULL) { oidc_error(r, "JSON parsing returned an error: %s", json_error.text); } else { if (!json_is_object(json)) { oidc_error(r, "parsed JSON did not contain a JSON object"); } else { oidc_util_json_merge(json, data); } json_decref(json); } } /* dynamically register the client with the specified parameters */ if (oidc_util_http_post_json(r, provider->registration_endpoint_url, data, NULL, provider->registration_token, provider->ssl_validate_server, response, cfg->http_timeout_short, cfg->outgoing_proxy, dir_cfg->pass_cookies) == FALSE) { json_decref(data); return FALSE; } json_decref(data); /* decode and see if it is not an error response somehow */ return oidc_util_decode_json_and_check_error(r, *response, j_client); }