diff --git a/docs/images/sample_okta_dsn.png b/docs/images/sample_okta_dsn.png index bae15d46c..cc7f187a5 100644 Binary files a/docs/images/sample_okta_dsn.png and b/docs/images/sample_okta_dsn.png differ diff --git a/docs/using-the-aws-driver/OktaAuthentication.md b/docs/using-the-aws-driver/OktaAuthentication.md index 40d15850c..a691dc3ea 100644 --- a/docs/using-the-aws-driver/OktaAuthentication.md +++ b/docs/using-the-aws-driver/OktaAuthentication.md @@ -34,12 +34,12 @@ When a user wants access to a resource, it authenticates with the IdP. From this | `APP_ID` | Yes | The Amazon Web Services (AWS) app [configured](https://help.okta.com/en-us/content/topics/deploymentguides/aws/aws-configure-aws-app.htm) on Okta. | `null` | `ec2amaz-ab3cdef.example.com` | | `IAM_ROLE_ARN` | Yes | The ARN of the IAM Role that is to be assumed to access AWS Aurora. | `null` | `arn:aws:iam::123456789012:role/adfs_example_iam_role` | | `IAM_IDP_ARN` | Yes | The ARN of the Identity Provider. | `null` | `arn:aws:iam::123456789012:saml-provider/adfs_example` | -| `AWS_REGION` | Yes | The AWS region where the identity provider is located. | `null` | `us-east-2` | +| `FED_AWS_REGION` | Yes | The AWS region where the identity provider is located. | `null` | `us-east-2` | | `USERNAME` | Yes | The Username must be set to the [IAM database user](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html). | `null` | `jane_doe` | -| `IDP_PORT` | No | The port that the host for the authentication service listens at. | `null` | `443` | -| `IAM_HOST` | No | Overrides the host used to generate the authentication token. This is useful when you are connecting using a custom endpoint, since authentication tokens need to be generated using the RDS/Aurora endpoints. | `null` | `database.cluster-hash.region.rds.amazonaws.com` | -| `IAM_DEFAULT_PORT` | No | This property overrides the default port that is used to generate the authentication token. The default port is the default MySQL port. | `3306` | `1234` | -| `IAM_TOKEN_EXPIRATION` | No | Overrides the default IAM token cache expiration in seconds. | `900` | `123` | +| `IDP_PORT` | No | The port that the host for the authentication service listens at. | `443` | `443` | +| `FED_AUTH_HOST` | No | Overrides the host used to generate the authentication token. This is useful when you are connecting using a custom endpoint, since authentication tokens need to be generated using the RDS/Aurora endpoints. | `null` | `database.cluster-hash.region.rds.amazonaws.com` | +| `FED_AUTH_DEFAULT_PORT` | No | This property overrides the default port that is used to generate the authentication token. The default port is the default MySQL port. | `3306` | `1234` | +| `FED_AUTH_EXPIRATION_TIME`| No | Overrides the default IAM token cache expiration in seconds. | `900` | `123` | | `CLIENT_SOCKET_TIMEOUT` | No | The read and write timeout value in seconds for the HttpClient used during the Okta authentication workflow. | `60` | `30` | | `CLIENT_CONNECT_TIMEOUT` | No | The connect timeout value in seconds for the HttpClient used during the Okta authentication workflow. | `60` | `30` | | `ENABLE_SSL` | No | Set to false to disable server certificate verification. Useful during local development when testing locally hosted servers using self-signed certificates. Not recommended for production. | `true` | `false` | diff --git a/driver/iam_proxy.cc b/driver/iam_proxy.cc index 25a60af02..47c5da0f5 100644 --- a/driver/iam_proxy.cc +++ b/driver/iam_proxy.cc @@ -39,11 +39,8 @@ IAM_PROXY::IAM_PROXY(DBC* dbc, DataSource* ds) : IAM_PROXY(dbc, ds, nullptr) {}; IAM_PROXY::IAM_PROXY(DBC* dbc, DataSource* ds, CONNECTION_PROXY* next_proxy) : CONNECTION_PROXY(dbc, ds) { this->next_proxy = next_proxy; - if (ds->opt_AUTH_REGION) { - this->auth_util = std::make_shared((const char*)ds->opt_AUTH_REGION); - } else { - this->auth_util = std::make_shared(); - } + const char* region = ds->opt_AUTH_REGION ? static_cast(ds->opt_AUTH_REGION) : Aws::Region::US_EAST_1; + this->auth_util = std::make_shared(region); } IAM_PROXY::~IAM_PROXY() { diff --git a/driver/okta_proxy.cc b/driver/okta_proxy.cc index 822d9791c..fffe9e437 100644 --- a/driver/okta_proxy.cc +++ b/driver/okta_proxy.cc @@ -42,11 +42,13 @@ OKTA_PROXY::OKTA_PROXY(DBC* dbc, DataSource* ds) : OKTA_PROXY(dbc, ds, nullptr) OKTA_PROXY::OKTA_PROXY(DBC* dbc, DataSource* ds, CONNECTION_PROXY* next_proxy) : CONNECTION_PROXY(dbc, ds) { this->next_proxy = next_proxy; - const std::string idp_host{static_cast(ds->opt_IDP_ENDPOINT)}; + std::string host{static_cast(ds->opt_IDP_ENDPOINT)}; + host += ":" + std::to_string(ds->opt_IDP_PORT); + const int client_connect_timeout = ds->opt_CLIENT_CONNECT_TIMEOUT; const int client_socket_timeout = ds->opt_CLIENT_SOCKET_TIMEOUT; const bool enable_ssl = ds->opt_ENABLE_SSL; - this->saml_util = std::make_shared(idp_host, client_connect_timeout, client_socket_timeout, enable_ssl); + this->saml_util = std::make_shared(host, client_connect_timeout, client_socket_timeout, enable_ssl); } bool OKTA_PROXY::connect(const char* host, const char* user, const char* password, const char* database, @@ -57,7 +59,7 @@ bool OKTA_PROXY::connect(const char* host, const char* user, const char* passwor } bool OKTA_PROXY::invoke_func_with_fed_credentials(std::function func) { - const char* region = ds->opt_AUTH_REGION ? static_cast(ds->opt_AUTH_REGION) : Aws::Region::US_EAST_1; + const char* region = ds->opt_FED_AUTH_REGION ? static_cast(ds->opt_FED_AUTH_REGION) : Aws::Region::US_EAST_1; std::string assertion; try { assertion = this->saml_util->get_saml_assertion(ds); @@ -74,8 +76,8 @@ bool OKTA_PROXY::invoke_func_with_fed_credentials(std::functionauth_util = std::make_shared(region, credentials); const char* AUTH_HOST = - ds->opt_AUTH_HOST ? static_cast(ds->opt_AUTH_HOST) : static_cast(ds->opt_SERVER); - int auth_port = ds->opt_AUTH_PORT; + ds->opt_FED_AUTH_HOST ? static_cast(ds->opt_FED_AUTH_HOST) : static_cast(ds->opt_SERVER); + int auth_port = ds->opt_FED_AUTH_PORT; if (auth_port == UNDEFINED_PORT) { // Use regular port if user does not provide an alternative port for AWS authentication auth_port = ds->opt_PORT; diff --git a/setupgui/callbacks.cc b/setupgui/callbacks.cc index 1204a450a..53177485b 100644 --- a/setupgui/callbacks.cc +++ b/setupgui/callbacks.cc @@ -338,10 +338,13 @@ void syncTabsData(HWND hwnd, DataSource *params) GET_STRING_TAB(FED_AUTH_TAB, IAM_ROLE_ARN); GET_STRING_TAB(FED_AUTH_TAB, IAM_IDP_ARN); GET_UNSIGNED_TAB(FED_AUTH_TAB, IDP_PORT); - GET_STRING_TAB(FED_AUTH_TAB, AUTH_REGION); - GET_STRING_TAB(FED_AUTH_TAB, AUTH_HOST); - GET_UNSIGNED_TAB(FED_AUTH_TAB, AUTH_PORT); - GET_UNSIGNED_TAB(FED_AUTH_TAB, AUTH_EXPIRATION); + GET_STRING_TAB(FED_AUTH_TAB, FED_AUTH_REGION); + GET_STRING_TAB(FED_AUTH_TAB, FED_AUTH_HOST); + GET_UNSIGNED_TAB(FED_AUTH_TAB, FED_AUTH_PORT); + GET_UNSIGNED_TAB(FED_AUTH_TAB, FED_AUTH_EXPIRATION); + GET_UNSIGNED_TAB(FED_AUTH_TAB, CLIENT_CONNECT_TIMEOUT); + GET_UNSIGNED_TAB(FED_AUTH_TAB, CLIENT_SOCKET_TIMEOUT); + GET_BOOL_TAB(FED_AUTH_TAB, ENABLE_SSL); /* 5 - Failover */ GET_BOOL_TAB(FAILOVER_TAB, ENABLE_CLUSTER_FAILOVER); @@ -490,10 +493,10 @@ void syncTabs(HWND hwnd, DataSource *params) SET_STRING_TAB(FED_AUTH_TAB, IAM_ROLE_ARN); SET_STRING_TAB(FED_AUTH_TAB, IAM_IDP_ARN); SET_UNSIGNED_TAB(FED_AUTH_TAB, IDP_PORT); - SET_STRING_TAB(FED_AUTH_TAB, AUTH_REGION); - SET_STRING_TAB(FED_AUTH_TAB, AUTH_HOST); - SET_UNSIGNED_TAB(FED_AUTH_TAB, AUTH_PORT); - SET_UNSIGNED_TAB(FED_AUTH_TAB, AUTH_EXPIRATION); + SET_STRING_TAB(FED_AUTH_TAB, FED_AUTH_REGION); + SET_STRING_TAB(FED_AUTH_TAB, FED_AUTH_HOST); + SET_UNSIGNED_TAB(FED_AUTH_TAB, FED_AUTH_PORT); + SET_UNSIGNED_TAB(FED_AUTH_TAB, FED_AUTH_EXPIRATION); SET_UNSIGNED_TAB(FED_AUTH_TAB, CLIENT_CONNECT_TIMEOUT); SET_UNSIGNED_TAB(FED_AUTH_TAB, CLIENT_SOCKET_TIMEOUT); SET_BOOL_TAB(FED_AUTH_TAB, ENABLE_SSL); diff --git a/setupgui/windows/odbcdialogparams.rc b/setupgui/windows/odbcdialogparams.rc index 2a5709e85..e0b6f325a 100644 --- a/setupgui/windows/odbcdialogparams.rc +++ b/setupgui/windows/odbcdialogparams.rc @@ -238,13 +238,13 @@ BEGIN LTEXT "IDP Port:",IDC_STATIC,207,125,36,10 EDITTEXT IDC_EDIT_IDP_PORT,243,124,51,12,ES_AUTOHSCROLL | ES_NUMBER RTEXT "AWS Region:",IDC_STATIC,3,126,58,18 - EDITTEXT IDC_EDIT_AUTH_REGION,65,125,136,12,ES_AUTOHSCROLL - RTEXT "IAM Host:",IDC_STATIC,3,145,58,18 - EDITTEXT IDC_EDIT_AUTH_HOST,65,144,136,12,ES_AUTOHSCROLL - LTEXT "IAM Port:",IDC_STATIC,207,144,36,18 - EDITTEXT IDC_EDIT_AUTH_PORT,244,143,51,12,ES_AUTOHSCROLL | ES_NUMBER - RTEXT "IAM Expire Time:",IDC_STATIC,3,163,58,18 - EDITTEXT IDC_EDIT_AUTH_EXPIRATION,65,162,136,12,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_EDIT_FED_AUTH_REGION,65,125,136,12,ES_AUTOHSCROLL + RTEXT "Auth Host:",IDC_STATIC,3,145,58,18 + EDITTEXT IDC_EDIT_FED_AUTH_HOST,65,144,136,12,ES_AUTOHSCROLL + LTEXT "Auth Port:",IDC_STATIC,207,144,36,18 + EDITTEXT IDC_EDIT_FED_AUTH_PORT,244,143,51,12,ES_AUTOHSCROLL | ES_NUMBER + RTEXT "Auth Expire Time:",IDC_STATIC,3,163,58,18 + EDITTEXT IDC_EDIT_FED_AUTH_EXPIRATION,65,162,136,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Client Connect Timeout:",IDC_STATIC,207,47,86,10 EDITTEXT IDC_EDIT_CLIENT_CONNECT_TIMEOUT,207,59,51,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Client Socket Timeout:",IDC_STATIC,207,76,75,10 diff --git a/setupgui/windows/resource.h b/setupgui/windows/resource.h index 524976faf..dcf7f33c3 100644 --- a/setupgui/windows/resource.h +++ b/setupgui/windows/resource.h @@ -195,6 +195,10 @@ #define IDC_EDIT_CLIENT_CONNECT_TIMEOUT 11028 #define IDC_EDIT_CLIENT_SOCKET_TIMEOUT 11029 #define IDC_CHECK_ENABLE_SSL 11030 +#define IDC_EDIT_FED_AUTH_REGION 11031 +#define IDC_EDIT_FED_AUTH_HOST 11032 +#define IDC_EDIT_FED_AUTH_PORT 11033 +#define IDC_EDIT_FED_AUTH_EXPIRATION 11034 #define MYSQL_ADMIN_PORT 33062 #define IDC_STATIC -1 diff --git a/util/installer.cc b/util/installer.cc index d8c8c551b..e5978810a 100644 --- a/util/installer.cc +++ b/util/installer.cc @@ -256,6 +256,10 @@ static SQLWCHAR W_IDP_PORT[] = { 'I', 'D', 'P', '_', 'P', 'O', 'R', 'T', 0 }; static SQLWCHAR W_CLIENT_CONNECT_TIMEOUT[] = {'C', 'L', 'I', 'E', 'N', 'T', '_', 'C', 'O', 'N', 'N', 'E', 'C', 'T', '_', 'T', 'I', 'M', 'E', 'O', 'U', 'T', 0}; static SQLWCHAR W_CLIENT_SOCKET_TIMEOUT[] = {'C', 'L', 'I', 'E', 'N', 'T', '_', 'S', 'O', 'C', 'K', 'E', 'T', '_', 'T', 'I', 'M', 'E', 'O', 'U', 'T', 0}; static SQLWCHAR W_ENABLE_SSL[] = {'E', 'N', 'A', 'B', 'L', 'E', '_', 'S', 'S', 'L', 0}; +static SQLWCHAR W_FED_AUTH_REGION[] = { 'F', 'E', 'D', '_', 'A', 'W', 'S', '_', 'R', 'E', 'G', 'I', 'O', 'N', 0 }; +static SQLWCHAR W_FED_AUTH_HOST[] = { 'F', 'E', 'D', '_','A', 'U', 'T', 'H', '_', 'H', 'O', 'S', 'T', 0 }; +static SQLWCHAR W_FED_AUTH_PORT[] = { 'F', 'E', 'D', '_','A', 'U', 'T', 'H', '_', 'P', 'O', 'R', 'T', 0 }; +static SQLWCHAR W_FED_AUTH_EXPIRATION[] = { 'F', 'E', 'D', '_', 'A', 'U', 'T', 'H', '_', 'E', 'X', 'P', 'I', 'R', 'A', 'T', 'I', 'O', 'N', '_', 'T', 'I', 'M', 'E', 0 }; /* Failover */ static SQLWCHAR W_ENABLE_CLUSTER_FAILOVER[] = { 'E', 'N', 'A', 'B', 'L', 'E', '_', 'C', 'L', 'U', 'S', 'T', 'E', 'R', '_', 'F', 'A', 'I', 'L', 'O', 'V', 'E', 'R', 0 }; @@ -325,6 +329,7 @@ SQLWCHAR *dsnparams[]= {W_DSN, W_DRIVER, W_DESCRIPTION, W_SERVER, /* FED Auth*/ W_IDP_USERNAME, W_IDP_PASSWORD, W_IDP_ENDPOINT, W_IDP_PORT, W_APP_ID, W_IAM_ROLE_ARN, W_IAM_IDP_ARN, W_CLIENT_CONNECT_TIMEOUT, W_CLIENT_SOCKET_TIMEOUT, W_ENABLE_SSL, + W_FED_AUTH_REGION, W_FED_AUTH_REGION, W_FED_AUTH_PORT, W_FED_AUTH_EXPIRATION, /* Failover */ W_ENABLE_CLUSTER_FAILOVER, W_FAILOVER_MODE, W_GATHER_PERF_METRICS, W_GATHER_PERF_METRICS_PER_INSTANCE, @@ -1057,6 +1062,9 @@ void DataSource::reset() { this->opt_AUTH_PORT.set_default(opt_PORT); this->opt_AUTH_EXPIRATION.set_default(900); // 15 minutes + this->opt_FED_AUTH_PORT.set_default(opt_PORT); + this->opt_FED_AUTH_EXPIRATION.set_default(900); // 15 minutes + this->opt_IDP_PORT.set_default(443); this->opt_CLIENT_CONNECT_TIMEOUT.set_default(60); this->opt_CLIENT_SOCKET_TIMEOUT.set_default(60); this->opt_ENABLE_SSL.set_default(true); diff --git a/util/installer.h b/util/installer.h index 22cd711da..7968cfc4b 100644 --- a/util/installer.h +++ b/util/installer.h @@ -317,17 +317,21 @@ unsigned int get_network_timeout(unsigned int seconds); #define FED_AUTH_STR_OPTIONS_LIST(X) \ X(FED_AUTH_MODE) \ - X(IDP_USERNAME) \ + X(IDP_USERNAME) \ X(IDP_PASSWORD) \ X(IDP_ENDPOINT) \ X(IAM_ROLE_ARN) \ X(IAM_IDP_ARN) \ - X(APP_ID) + X(APP_ID) \ + X(FED_AUTH_HOST) \ + X(FED_AUTH_REGION) #define FED_AUTH_INT_OPTIONS_LIST(X) \ X(IDP_PORT) \ X(CLIENT_SOCKET_TIMEOUT) \ - X(CLIENT_CONNECT_TIMEOUT) + X(CLIENT_CONNECT_TIMEOUT) \ + X(FED_AUTH_PORT) \ + X(FED_AUTH_EXPIRATION) #define FED_AUTH_BOOL_OPTIONS_LIST(X) \ X(ENABLE_SSL)