From 9e5826f40fbc633c7b7b822faf7f338e85e4ecc0 Mon Sep 17 00:00:00 2001 From: Misi Date: Fri, 15 Dec 2023 13:20:17 +0100 Subject: [PATCH] OAuth: Remove accessTokenExpirationCheck feature toggle (#79455) * Remove accessTokenExpirationCheck from code and align docs * Apply suggestions from code review * lint --------- Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com> --- .../configure-grafana/feature-toggles/index.md | 1 - .../configure-authentication/azuread/index.md | 8 ++------ .../configure-authentication/generic-oauth/index.md | 10 ++++------ .../configure-authentication/gitlab/index.md | 12 +++++------- .../configure-authentication/google/index.md | 8 ++++---- .../configure-authentication/keycloak/index.md | 8 +++++--- .../configure-authentication/okta/index.md | 8 ++++---- .../grafana-data/src/types/featureToggles.gen.ts | 1 - pkg/login/social/connectors/azuread_oauth.go | 2 +- pkg/login/social/connectors/google_oauth.go | 2 +- pkg/login/social/connectors/okta_oauth.go | 2 +- pkg/services/authn/authnimpl/service.go | 6 +----- pkg/services/featuremgmt/registry.go | 8 -------- pkg/services/featuremgmt/toggles_gen.csv | 1 - pkg/services/featuremgmt/toggles_gen.go | 4 ---- 15 files changed, 28 insertions(+), 53 deletions(-) diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 8745ccf68b0..7f7b9304148 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -32,7 +32,6 @@ Some features are enabled by default. You can disable these feature by setting t | `athenaAsyncQueryDataSupport` | Enable async query data support for Athena | Yes | | `cloudwatchNewRegionsHandler` | Refactor of /regions endpoint, no user-facing changes | Yes | | `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes | -| `accessTokenExpirationCheck` | Enable OAuth access_token expiration check and token refresh using the refresh_token | | | `emptyDashboardPage` | Enable the redesigned user interface of a dashboard page that includes no panels | Yes | | `disablePrometheusExemplarSampling` | Disable Prometheus exemplar sampling | | | `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md index b6d638d4e6d..9b6f5b7ad5c 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md @@ -200,17 +200,13 @@ Verify that the Grafana [root_url]({{< relref "../../../configure-grafana#root_u > Available in Grafana v9.3 and later versions. -{{% admonition type="note" %}} -This feature is behind the `accessTokenExpirationCheck` feature toggle. -{{% /admonition %}} - When a user logs in using an OAuth provider, Grafana verifies that the access token has not expired. When an access token expires, Grafana uses the provided refresh token (if any exists) to obtain a new access token. Grafana uses a refresh token to obtain a new access token without requiring the user to log in again. If a refresh token doesn't exist, Grafana logs the user out of the system after the access token has expired. -Refresh token fetching and access token expiration check is enabled by default for the AzureAD provider since Grafana v10.1.0 if the `accessTokenExpirationCheck` feature toggle is enabled. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. +Refresh token fetching and access token expiration check is enabled by default for the AzureAD provider since Grafana v10.1.0. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +> **Note:** The `accessTokenExpirationCheck` feature toggle has been removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. ### Configure allowed tenants diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md index cabe8e6abec..0e0c2d60d40 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md @@ -67,13 +67,11 @@ To integrate your OAuth2 provider with Grafana using our generic OAuth2 authenti 1. Optional: [Configure a refresh token]({{< relref "#configure-a-refresh-token" >}}): - a. Enable `accessTokenExpirationCheck` feature toggle. + a. Extend the `scopes` field of `[auth.generic_oauth]` section in Grafana configuration file with refresh token scope used by your OAuth2 provider. - b. Extend the `scopes` field of `[auth.generic_oauth]` section in Grafana configuration file with refresh token scope used by your OAuth2 provider. + b. Set `use_refresh_token` to `true` in `[auth.generic_oauth]` section in Grafana configuration file. - c. Set `use_refresh_token` to `true` in `[auth.generic_oauth]` section in Grafana configuration file. - - d. Enable the refresh token on the provider if required. + c. Enable the refresh token on the provider if required. 1. [Configure role mapping]({{< relref "#configure-role-mapping" >}}). 1. Optional: [Configure team synchronization]({{< relref "#configure-team-synchronization" >}}). @@ -121,7 +119,7 @@ The following table outlines the various generic OAuth2 configuration options. Y | `tls_client_key` | No | The path to the key. | | | `tls_client_ca` | No | The path to the trusted certificate authority list. | | | `use_pkce` | No | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `false` | -| `use_refresh_token` | No | Set to `true` to use refresh token and check access token expiration. The `accessTokenExpirationCheck` feature toggle should also be enabled to use refresh token. | `false` | +| `use_refresh_token` | No | Set to `true` to use refresh token and check access token expiration. | `false` | ### Configure login diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md index e72ab414408..8f2b8107331 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md @@ -55,9 +55,7 @@ To configure GitLab authentication with Grafana, follow these steps: 1. Optional: [Configure a refresh token]({{< relref "#configure-a-refresh-token" >}}): - a. Enable `accessTokenExpirationCheck` feature toggle. - - b. Set `use_refresh_token` to `true` in `[auth.gitlab]` section in Grafana configuration file. + a. Set `use_refresh_token` to `true` in `[auth.gitlab]` section in Grafana configuration file. 1. [Configure role mapping]({{< relref "#configure-role-mapping" >}}). 1. Optional: [Configure team synchronization]({{< relref "#configure-team-synchronization" >}}). @@ -99,17 +97,17 @@ The table below describes all GitLab OAuth configuration options. Like any other > Available in Grafana v9.3 and later versions. -> **Note:** This feature is behind the `accessTokenExpirationCheck` feature toggle. - When a user logs in using an OAuth provider, Grafana verifies that the access token has not expired. When an access token expires, Grafana uses the provided refresh token (if any exists) to obtain a new access token. Grafana uses a refresh token to obtain a new access token without requiring the user to log in again. If a refresh token doesn't exist, Grafana logs the user out of the system after the access token has expired. By default, GitLab provides a refresh token. -Refresh token fetching and access token expiration check is enabled by default for the GitLab provider since Grafana v10.1.0 if the `accessTokenExpirationCheck` feature toggle is enabled. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. +Refresh token fetching and access token expiration check is enabled by default for the GitLab provider since Grafana v10.1.0. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +{{% admonition type="note" %}} +The `accessTokenExpirationCheck` feature toggle has been removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +{{% /admonition %}} ### Configure allowed groups diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md index 90f05b62f3c..73c2b2a0497 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md @@ -79,17 +79,17 @@ interception attacks. PKCE will be required in [OAuth 2.1](https://datatracker.i > Available in Grafana v9.3 and later versions. -> **Note:** This feature is behind the `accessTokenExpirationCheck` feature toggle. - When a user logs in using an OAuth provider, Grafana verifies that the access token has not expired. When an access token expires, Grafana uses the provided refresh token (if any exists) to obtain a new access token. Grafana uses a refresh token to obtain a new access token without requiring the user to log in again. If a refresh token doesn't exist, Grafana logs the user out of the system after the access token has expired. By default, Grafana includes the `access_type=offline` parameter in the authorization request to request a refresh token. -Refresh token fetching and access token expiration check is enabled by default for the Google provider since Grafana v10.1.0 if the `accessTokenExpirationCheck` feature toggle is enabled. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. +Refresh token fetching and access token expiration check is enabled by default for the Google provider since Grafana v10.1.0. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +{{% admonition type="note" %}} +The `accessTokenExpirationCheck` feature toggle has been removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +{{% /admonition %}} ### Configure automatic login diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md index 7dfef927013..2d0a30f8fe3 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md @@ -164,10 +164,12 @@ allow_assign_grafana_admin = true > Available in Grafana v9.3 and later versions. -> **Note:** This feature is behind the `accessTokenExpirationCheck` feature toggle. - When a user logs in using an OAuth provider, Grafana verifies that the access token has not expired. When an access token expires, Grafana uses the provided refresh token (if any exists) to obtain a new access token. Grafana uses a refresh token to obtain a new access token without requiring the user to log in again. If a refresh token doesn't exist, Grafana logs the user out of the system after the access token has expired. -To enable a refresh token for Keycloak, extend the `scopes` in `[auth.generic_oauth]` with `offline_access`. +To enable a refresh token for Keycloak, do the following: + +1. Extend the `scopes` in `[auth.generic_oauth]` with `offline_access`. + +1. Add `use_refresh_token = true` to `[auth.generic_oauth]` configuration. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md index 4a8245954a1..b11bcf11021 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md @@ -110,14 +110,12 @@ The following table outlines the various Okta OIDC configuration options. You ca | `allowed_groups` | No | List of comma- or space-separated groups. The user should be a member of at least one group to log in. | | | `allowed_domains` | No | List comma- or space-separated domains. The user should belong to at least one domain to log in. | | | `use_pkce` | No | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | -| `use_refresh_token` | No | Set to `true` to use refresh token and check access token expiration. The `accessTokenExpirationCheck` feature toggle should also be enabled to use refresh token. | `false` | +| `use_refresh_token` | No | Set to `true` to use refresh token and check access token expiration. | `false` | ### Configure a refresh token > Available in Grafana v9.3 and later versions. -> **Note:** This feature is behind the `accessTokenExpirationCheck` feature toggle. - When a user logs in using an OAuth provider, Grafana verifies that the access token has not expired. When an access token expires, Grafana uses the provided refresh token (if any exists) to obtain a new access token without requiring the user to log in again. If a refresh token doesn't exist, Grafana logs the user out of the system after the access token has expired. @@ -129,7 +127,9 @@ To enable the `Refresh Token` head over the Okta application settings and: At the configuration file, extend the `scopes` in `[auth.okta]` section with `offline_access`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +{{% admonition type="note" %}} +The `accessTokenExpirationCheck` feature toggle has been removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +{{% /admonition %}} ### Configure role mapping diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 737cc8ca7e0..ad614af6da5 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -53,7 +53,6 @@ export interface FeatureToggles { accessControlOnCall?: boolean; nestedFolders?: boolean; nestedFolderPicker?: boolean; - accessTokenExpirationCheck?: boolean; emptyDashboardPage?: boolean; disablePrometheusExemplarSampling?: boolean; alertingBacktesting?: boolean; diff --git a/pkg/login/social/connectors/azuread_oauth.go b/pkg/login/social/connectors/azuread_oauth.go index 3e8ccce19e5..a3ad4f3b858 100644 --- a/pkg/login/social/connectors/azuread_oauth.go +++ b/pkg/login/social/connectors/azuread_oauth.go @@ -81,7 +81,7 @@ func NewAzureADProvider(info *social.OAuthInfo, cfg *setting.Cfg, ssoSettings ss forceUseGraphAPI: MustBool(info.Extra[forceUseGraphAPIKey], false), } - if info.UseRefreshToken && features.IsEnabledGlobally(featuremgmt.FlagAccessTokenExpirationCheck) { + if info.UseRefreshToken { appendUniqueScope(config, social.OfflineAccessScope) } diff --git a/pkg/login/social/connectors/google_oauth.go b/pkg/login/social/connectors/google_oauth.go index 7d3391f13d6..bffc8f91b1c 100644 --- a/pkg/login/social/connectors/google_oauth.go +++ b/pkg/login/social/connectors/google_oauth.go @@ -168,7 +168,7 @@ func (s *SocialGoogle) extractFromAPI(ctx context.Context, client *http.Client) } func (s *SocialGoogle) AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string { - if s.features.IsEnabledGlobally(featuremgmt.FlagAccessTokenExpirationCheck) && s.info.UseRefreshToken { + if s.info.UseRefreshToken { opts = append(opts, oauth2.AccessTypeOffline, oauth2.ApprovalForce) } return s.SocialBase.AuthCodeURL(state, opts...) diff --git a/pkg/login/social/connectors/okta_oauth.go b/pkg/login/social/connectors/okta_oauth.go index ae0991add48..89f043c54c5 100644 --- a/pkg/login/social/connectors/okta_oauth.go +++ b/pkg/login/social/connectors/okta_oauth.go @@ -50,7 +50,7 @@ func NewOktaProvider(info *social.OAuthInfo, cfg *setting.Cfg, ssoSettings ssose SocialBase: newSocialBase(social.OktaProviderName, config, info, cfg.AutoAssignOrgRole, *features), } - if info.UseRefreshToken && features.IsEnabledGlobally(featuremgmt.FlagAccessTokenExpirationCheck) { + if info.UseRefreshToken { appendUniqueScope(config, social.OfflineAccessScope) } diff --git a/pkg/services/authn/authnimpl/service.go b/pkg/services/authn/authnimpl/service.go index b72fc43600a..ac191c0e299 100644 --- a/pkg/services/authn/authnimpl/service.go +++ b/pkg/services/authn/authnimpl/service.go @@ -158,11 +158,7 @@ func ProvideService( s.RegisterPostAuthHook(userSyncService.EnableUserHook, 20) s.RegisterPostAuthHook(orgUserSyncService.SyncOrgRolesHook, 30) s.RegisterPostAuthHook(userSyncService.SyncLastSeenHook, 120) - - if features.IsEnabledGlobally(featuremgmt.FlagAccessTokenExpirationCheck) { - s.RegisterPostAuthHook(sync.ProvideOAuthTokenSync(oauthTokenService, sessionService, socialService).SyncOauthTokenHook, 60) - } - + s.RegisterPostAuthHook(sync.ProvideOAuthTokenSync(oauthTokenService, sessionService, socialService).SyncOauthTokenHook, 60) s.RegisterPostAuthHook(userSyncService.FetchSyncedUserHook, 100) s.RegisterPostAuthHook(sync.ProvidePermissionsSync(accessControlService).SyncPermissionsHook, 110) diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index e526c0d94fc..c64d53050e2 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -306,14 +306,6 @@ var ( AllowSelfServe: truePtr, Created: time.Date(2023, time.July, 24, 12, 0, 0, 0, time.UTC), }, - { - Name: "accessTokenExpirationCheck", - Description: "Enable OAuth access_token expiration check and token refresh using the refresh_token", - Stage: FeatureStageGeneralAvailability, - Owner: identityAccessTeam, - AllowSelfServe: falsePtr, - Created: time.Date(2022, time.November, 14, 12, 0, 0, 0, time.UTC), - }, { Name: "emptyDashboardPage", Description: "Enable the redesigned user interface of a dashboard page that includes no panels", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 95730856a77..d991e72a2d1 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -34,7 +34,6 @@ mysqlAnsiQuotes,experimental,@grafana/backend-platform,2022-10-12,false,false,fa accessControlOnCall,preview,@grafana/identity-access-team,2022-10-19,false,false,false,false nestedFolders,preview,@grafana/backend-platform,2022-10-22,false,false,false,false nestedFolderPicker,GA,@grafana/grafana-frontend-platform,2023-07-24,false,false,false,true -accessTokenExpirationCheck,GA,@grafana/identity-access-team,2022-11-14,false,false,false,false emptyDashboardPage,GA,@grafana/dashboards-squad,2023-03-28,false,false,false,true disablePrometheusExemplarSampling,GA,@grafana/observability-metrics,2022-12-19,false,false,false,false alertingBacktesting,experimental,@grafana/alerting-squad,2022-10-20,false,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index e98c75c7bb4..947a6621971 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -147,10 +147,6 @@ const ( // Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle FlagNestedFolderPicker = "nestedFolderPicker" - // FlagAccessTokenExpirationCheck - // Enable OAuth access_token expiration check and token refresh using the refresh_token - FlagAccessTokenExpirationCheck = "accessTokenExpirationCheck" - // FlagEmptyDashboardPage // Enable the redesigned user interface of a dashboard page that includes no panels FlagEmptyDashboardPage = "emptyDashboardPage"