OAuth: Support client_secret_jwt for oauth providers when doing token exchange (#95455)

* added backend support for client_secret_jwt

* added backend support for client_secret_jwt

* added all logic to the exchange function (overloaded social exchange in azuread_oauth to handle managed identity client id)

* ran yarn install to update lock file

* added support for client_secret_jwt when managed_identity_client_id is null

* added audience flag and changed exchange to directly access oauth config using .info

* added logic in setting oauth.Config for supported client authentication values

* added client_authentication, managed_identity_client_id, and audience to sample.ini file

* using provided ctx in ManagedIdentityCallback function

* added frontend support for federated identity credential auth

* added client authentication field

* added Azure AD documentation for Grafana

* added bold font to "Add" keyword in documentation

* minor wording change relating to previous commit

* addressed changing audience to federated_credential_audience, moving validation, and changing managedIdentityCallback to private function

* correction to audience name changing

* fixed orgMappingClientAuthentication function name, and added in logic into validateFederatedCredentialAudience function

* Change docs

* Add iam team as owner of azcore pkg

* added backend support for client_secret_jwt

* added all logic to the exchange function (overloaded social exchange in azuread_oauth to handle managed identity client id)

* ran yarn install to update lock file

* added support for client_secret_jwt when managed_identity_client_id is null

* added audience flag and changed exchange to directly access oauth config using .info

* added logic in setting oauth.Config for supported client authentication values

* added client_authentication, managed_identity_client_id, and audience to sample.ini file

* using provided ctx in ManagedIdentityCallback function

* added frontend support for federated identity credential auth

* added client authentication field

* added Azure AD documentation for Grafana

* added bold font to "Add" keyword in documentation

* minor wording change relating to previous commit

* addressed changing audience to federated_credential_audience, moving validation, and changing managedIdentityCallback to private function

* correction to audience name changing

* fixed orgMappingClientAuthentication function name, and added in logic into validateFederatedCredentialAudience function

* Change docs

* Add iam team as owner of azcore pkg

* updated yarn lock file

* updated doc for correction

* removed wrong changes in pkg directory

* removed newline in dashboard-generate.yaml and unified.ts

* updated yarn.lock to match upstream

* Lint

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* removing unwanted changes

* added back removed newline

* fixed failing test in azuread_oauth_test.go

* Update azuread_oauth.go

removed unnecessary newline, fixed lint

---------

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
Co-authored-by: Mihaly Gyongyosi <mgyongyosi@users.noreply.github.com>
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
This commit is contained in:
John Naizer
2025-01-07 10:42:52 +01:00
committed by GitHub
co-authored by Mihaly Gyongyosi Jack Baldry
parent d96f378562
commit 79d565f285
14 changed files with 407 additions and 163 deletions
@@ -70,40 +70,43 @@ func (s *OAuthStrategy) loadSettingsForProvider(provider string) map[string]any
section := s.cfg.Raw.Section("auth." + provider)
result := map[string]any{
"client_id": section.Key("client_id").Value(),
"client_secret": section.Key("client_secret").Value(),
"scopes": section.Key("scopes").Value(),
"empty_scopes": section.Key("empty_scopes").MustBool(false),
"auth_style": section.Key("auth_style").Value(),
"auth_url": section.Key("auth_url").Value(),
"token_url": section.Key("token_url").Value(),
"api_url": section.Key("api_url").Value(),
"teams_url": section.Key("teams_url").Value(),
"enabled": section.Key("enabled").MustBool(false),
"email_attribute_name": section.Key("email_attribute_name").Value(),
"email_attribute_path": section.Key("email_attribute_path").Value(),
"role_attribute_path": section.Key("role_attribute_path").Value(),
"role_attribute_strict": section.Key("role_attribute_strict").MustBool(false),
"groups_attribute_path": section.Key("groups_attribute_path").Value(),
"team_ids_attribute_path": section.Key("team_ids_attribute_path").Value(),
"allowed_domains": section.Key("allowed_domains").Value(),
"hosted_domain": section.Key("hosted_domain").Value(),
"allow_sign_up": section.Key("allow_sign_up").MustBool(false),
"name": section.Key("name").Value(),
"icon": section.Key("icon").Value(),
"skip_org_role_sync": section.Key("skip_org_role_sync").MustBool(false),
"tls_client_cert": section.Key("tls_client_cert").Value(),
"tls_client_key": section.Key("tls_client_key").Value(),
"tls_client_ca": section.Key("tls_client_ca").Value(),
"tls_skip_verify_insecure": section.Key("tls_skip_verify_insecure").MustBool(false),
"use_pkce": section.Key("use_pkce").MustBool(false),
"use_refresh_token": section.Key("use_refresh_token").MustBool(false),
"allow_assign_grafana_admin": section.Key("allow_assign_grafana_admin").MustBool(false),
"auto_login": section.Key("auto_login").MustBool(false),
"allowed_groups": section.Key("allowed_groups").Value(),
"signout_redirect_url": section.Key("signout_redirect_url").Value(),
"org_mapping": section.Key("org_mapping").Value(),
"org_attribute_path": section.Key("org_attribute_path").Value(),
"client_authentication": section.Key("client_authentication").Value(),
"client_id": section.Key("client_id").Value(),
"client_secret": section.Key("client_secret").Value(),
"managed_identity_client_id": section.Key("managed_identity_client_id").Value(),
"federated_credential_audience": section.Key("federated_credential_audience").Value(),
"scopes": section.Key("scopes").Value(),
"empty_scopes": section.Key("empty_scopes").MustBool(false),
"auth_style": section.Key("auth_style").Value(),
"auth_url": section.Key("auth_url").Value(),
"token_url": section.Key("token_url").Value(),
"api_url": section.Key("api_url").Value(),
"teams_url": section.Key("teams_url").Value(),
"enabled": section.Key("enabled").MustBool(false),
"email_attribute_name": section.Key("email_attribute_name").Value(),
"email_attribute_path": section.Key("email_attribute_path").Value(),
"role_attribute_path": section.Key("role_attribute_path").Value(),
"role_attribute_strict": section.Key("role_attribute_strict").MustBool(false),
"groups_attribute_path": section.Key("groups_attribute_path").Value(),
"team_ids_attribute_path": section.Key("team_ids_attribute_path").Value(),
"allowed_domains": section.Key("allowed_domains").Value(),
"hosted_domain": section.Key("hosted_domain").Value(),
"allow_sign_up": section.Key("allow_sign_up").MustBool(false),
"name": section.Key("name").Value(),
"icon": section.Key("icon").Value(),
"skip_org_role_sync": section.Key("skip_org_role_sync").MustBool(false),
"tls_client_cert": section.Key("tls_client_cert").Value(),
"tls_client_key": section.Key("tls_client_key").Value(),
"tls_client_ca": section.Key("tls_client_ca").Value(),
"tls_skip_verify_insecure": section.Key("tls_skip_verify_insecure").MustBool(false),
"use_pkce": section.Key("use_pkce").MustBool(false),
"use_refresh_token": section.Key("use_refresh_token").MustBool(false),
"allow_assign_grafana_admin": section.Key("allow_assign_grafana_admin").MustBool(false),
"auto_login": section.Key("auto_login").MustBool(false),
"allowed_groups": section.Key("allowed_groups").Value(),
"signout_redirect_url": section.Key("signout_redirect_url").Value(),
"org_mapping": section.Key("org_mapping").Value(),
"org_attribute_path": section.Key("org_attribute_path").Value(),
}
extraKeys := extraKeysByProvider[provider]
@@ -19,8 +19,11 @@ var (
enabled = true
allow_sign_up = false
auto_login = true
client_authentication = test_client_authentication
client_id = test_client_id
client_secret = test_client_secret
managed_identity_client_id = test_managed_identity_client_id
federated_credential_audience = test_federated_credential_audience
scopes = openid, profile, email
empty_scopes = false
email_attribute_name = email:primary
@@ -57,45 +60,48 @@ var (
`
expectedOAuthInfo = map[string]any{
"name": "OAuth",
"icon": "signin",
"enabled": true,
"allow_sign_up": false,
"auto_login": true,
"client_id": "test_client_id",
"client_secret": "test_client_secret",
"scopes": "openid, profile, email",
"empty_scopes": false,
"email_attribute_name": "email:primary",
"email_attribute_path": "email",
"role_attribute_path": "role",
"role_attribute_strict": true,
"groups_attribute_path": "groups",
"team_ids_attribute_path": "team_ids",
"auth_url": "test_auth_url",
"token_url": "test_token_url",
"api_url": "test_api_url",
"teams_url": "test_teams_url",
"allowed_domains": "domain1.com",
"allowed_groups": "",
"tls_skip_verify_insecure": true,
"tls_client_cert": "",
"tls_client_key": "",
"tls_client_ca": "",
"use_pkce": false,
"auth_style": "inheader",
"allow_assign_grafana_admin": true,
"use_refresh_token": true,
"hosted_domain": "test_hosted_domain",
"skip_org_role_sync": true,
"signout_redirect_url": "test_signout_redirect_url",
"allowed_organizations": "org1, org2",
"id_token_attribute_name": "id_token",
"login_attribute_path": "login",
"name_attribute_path": "name",
"team_ids": "first, second",
"org_attribute_path": "groups",
"org_mapping": "Group1:*:Editor",
"name": "OAuth",
"icon": "signin",
"enabled": true,
"allow_sign_up": false,
"auto_login": true,
"client_authentication": "test_client_authentication",
"client_id": "test_client_id",
"client_secret": "test_client_secret",
"managed_identity_client_id": "test_managed_identity_client_id",
"federated_credential_audience": "test_federated_credential_audience",
"scopes": "openid, profile, email",
"empty_scopes": false,
"email_attribute_name": "email:primary",
"email_attribute_path": "email",
"role_attribute_path": "role",
"role_attribute_strict": true,
"groups_attribute_path": "groups",
"team_ids_attribute_path": "team_ids",
"auth_url": "test_auth_url",
"token_url": "test_token_url",
"api_url": "test_api_url",
"teams_url": "test_teams_url",
"allowed_domains": "domain1.com",
"allowed_groups": "",
"tls_skip_verify_insecure": true,
"tls_client_cert": "",
"tls_client_key": "",
"tls_client_ca": "",
"use_pkce": false,
"auth_style": "inheader",
"allow_assign_grafana_admin": true,
"use_refresh_token": true,
"hosted_domain": "test_hosted_domain",
"skip_org_role_sync": true,
"signout_redirect_url": "test_signout_redirect_url",
"allowed_organizations": "org1, org2",
"id_token_attribute_name": "id_token",
"login_attribute_path": "login",
"name_attribute_path": "name",
"team_ids": "first, second",
"org_attribute_path": "groups",
"org_mapping": "Group1:*:Editor",
}
)