SSO: Add prompt param to SSO settings (#107969)

* add prompt param to AzureAD oauth config

* yarn i18n-extract

* validate auth prompt value

* make login_prompt available for all SSO providers

* use base authCodeURL for azure and google

* add docs for the new field for azure and generic oauth

* fix typo

* fix frontend unit test

* add prompt parameter to docs for the other providers

* remove prompt from okta

* add unit tests for the other providers

* address feedback

* add back translations for prompt labels
pull/107817/head
Mihai Doarna 3 days ago committed by GitHub
parent 807264428e
commit 8dfb4cdfc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md
  2. 1
      docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md
  3. 1
      docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md
  4. 1
      docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md
  5. 1
      docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md
  6. 2
      pkg/login/social/connectors/azuread_oauth.go
  7. 18
      pkg/login/social/connectors/azuread_oauth_test.go
  8. 19
      pkg/login/social/connectors/generic_oauth_test.go
  9. 14
      pkg/login/social/connectors/github_oauth_test.go
  10. 14
      pkg/login/social/connectors/gitlab_oauth_test.go
  11. 3
      pkg/login/social/connectors/google_oauth.go
  12. 14
      pkg/login/social/connectors/google_oauth_test.go
  13. 13
      pkg/login/social/connectors/social_base.go
  14. 1
      pkg/login/social/social.go
  15. 1
      pkg/services/ssosettings/strategies/oauth_strategy.go
  16. 2
      pkg/services/ssosettings/strategies/oauth_strategy_test.go
  17. 9
      pkg/services/ssosettings/validation/oauth_validators.go
  18. 2
      public/app/features/auth-config/ProviderConfigForm.test.tsx
  19. 51
      public/app/features/auth-config/fields.tsx
  20. 1
      public/app/features/auth-config/types.ts
  21. 1
      public/app/features/auth-config/utils/data.ts
  22. 5
      public/locales/en-US/grafana.json

@ -544,6 +544,7 @@ The following table outlines the various Azure AD/Entra ID configuration options
| `scopes` | No | Yes | List of comma- or space-separated OAuth2 scopes. | `openid email profile` |
| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Azure AD/Entra ID login. Only existing Grafana users can log in with Azure AD/Entra ID if set to `false`. | `true` |
| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` |
| `login_prompt` | No | Yes | Indicates the type of user interaction when the user logs in with Azure AD/Entra ID. Available values are `login`, `consent` and `select_account`. | |
| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Map roles](#map-roles). | `false` |
| `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no value is returned, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | |
| `org_mapping` | No | No | List of comma- or space-separated `<ExternalOrgName>:<OrgIdOrName>:<Role>` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | |

@ -376,6 +376,7 @@ If the configuration option requires a JMESPath expression that includes a colon
| `empty_scopes` | No | Yes | Set to `true` to use an empty scope during authentication. | `false` |
| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Generic OAuth login. Only existing Grafana users can log in with Generic OAuth if set to `false`. | `true` |
| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` |
| `login_prompt` | No | Yes | Indicates the type of user interaction when the user logs in with the IdP. Available values are `login`, `consent` and `select_account`. | |
| `id_token_attribute_name` | No | Yes | The name of the key used to extract the ID token from the returned OAuth2 token. | `id_token` |
| `login_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user login lookup from the user ID token. For more information on how user login is retrieved, refer to [Configure login](#configure-login). | |
| `name_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user name lookup from the user ID token. This name will be used as the user's display name. For more information on how user display name is retrieved, refer to [Configure display name](#configure-display-name). | |

@ -247,6 +247,7 @@ If the configuration option requires a JMESPath expression that includes a colon
| `scopes` | No | Yes | List of comma- or space-separated GitHub OAuth scopes. | `user:email,read:org` |
| `allow_sign_up` | No | Yes | Whether to allow new Grafana user creation through GitHub login. If set to `false`, then only existing Grafana users can log in with GitHub OAuth. | `true` |
| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` |
| `login_prompt` | No | Yes | Indicates the type of user interaction when the user logs in with GitHub. Available values are `login`, `consent` and `select_account`. | |
| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the user information obtained from the UserInfo endpoint. If no role is found, Grafana creates a JSON data with `groups` key that maps to GitHub teams obtained from GitHub's [`/api/user/teams`](https://docs.github.com/en/rest/teams/teams#list-teams-for-the-authenticated-user) endpoint, and evaluates the expression using this data. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping](#org-roles-mapping-example). | |
| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping](#org-roles-mapping-example). | `false` |
| `org_mapping` | No | No | List of comma- or space-separated `<ExternalGitHubTeamName>:<OrgIdOrName>:<Role>` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | |

@ -270,6 +270,7 @@ If the configuration option requires a JMESPath expression that includes a colon
| `scopes` | No | Yes | List of comma or space-separated GitLab OAuth scopes. | `openid email profile` |
| `allow_sign_up` | No | Yes | Whether to allow new Grafana user creation through GitLab login. If set to `false`, then only existing Grafana users can log in with GitLab OAuth. | `true` |
| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` |
| `login_prompt` | No | Yes | Indicates the type of user interaction when the user logs in with GitLab. Available values are `login`, `consent` and `select_account`. | |
| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the GitLab OAuth token. If no role is found, Grafana creates a JSON data with `groups` key that maps to groups obtained from GitLab's `/oauth/userinfo` endpoint, and evaluates the expression using this data. Finally, if a valid role is still not found, the expression is evaluated against the user information retrieved from `api_url/users` endpoint and groups retrieved from `api_url/groups` endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | |
| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana role cannot be extracted using `role_attribute_path`. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` |
| `org_mapping` | No | No | List of comma- or space-separated `<ExternalGitlabGroupName>:<OrgIdOrName>:<Role>` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | |

@ -290,6 +290,7 @@ The following table outlines the various Google OAuth configuration options. You
| `scopes` | No | Yes | List of comma- or space-separated OAuth2 scopes. | `openid email profile` |
| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Google login. Only existing Grafana users can log in with Google if set to `false`. | `true` |
| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` |
| `login_prompt` | No | Yes | Indicates the type of user interaction when the user logs in with Google. Available values are `login`, `consent` and `select_account`. | |
| `hosted_domain` | No | Yes | Specifies the domain to restrict access to users from that domain. This value is appended to the authorization request using the `hd` parameter. | |
| `validate_hd` | No | Yes | Set to `false` to disable the validation of the `hd` parameter from the Google ID token. For more informatiion, refer to [Enable Google OAuth in Grafana](#enable-google-oauth-in-grafana). | `true` |
| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` |

@ -336,7 +336,7 @@ func (s *SocialAzureAD) AuthCodeURL(state string, opts ...oauth2.AuthCodeOption)
opts = append(opts, oauth2.SetAuthURLParam("domain_hint", domainHint))
}
return s.Config.AuthCodeURL(state, opts...)
return s.getAuthCodeURL(state, opts...)
}
func (s *SocialAzureAD) validateIDTokenSignature(ctx context.Context, client *http.Client, parsedToken *jwt.JSONWebToken) (*azureClaims, error) {

@ -1276,6 +1276,22 @@ func TestSocialAzureAD_Validate(t *testing.T) {
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
{
name: "fails if login prompt is invalid",
settings: ssoModels.SSOSettings{
Settings: map[string]any{
"client_authentication": "client_secret_post",
"client_id": "client-id",
"client_secret": "client_secret",
"allowed_groups": "0bb9c9cc-4945-418f-9b6a-c1d3b81141b0, 6034d328-0e6a-4240-8d03-cb9f2c1f16e4",
"allow_assign_grafana_admin": "true",
"auth_url": "https://example.com/auth",
"token_url": "https://example.com/token",
"login_prompt": "invalid",
},
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
}
for _, tc := range testCases {
@ -1315,6 +1331,7 @@ func TestSocialAzureAD_Reload(t *testing.T) {
"client_id": "new-client-id",
"client_secret": "new-client-secret",
"auth_url": "some-new-url",
"login_prompt": "select_account",
},
},
expectError: false,
@ -1322,6 +1339,7 @@ func TestSocialAzureAD_Reload(t *testing.T) {
ClientId: "new-client-id",
ClientSecret: "new-client-secret",
AuthUrl: "some-new-url",
LoginPrompt: "select_account",
},
expectedConfig: &oauth2.Config{
ClientID: "new-client-id",

@ -1230,6 +1230,20 @@ func TestSocialGenericOAuth_Validate(t *testing.T) {
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
{
name: "fails if login prompt is invalid",
settings: ssoModels.SSOSettings{
Settings: map[string]any{
"client_id": "client-id",
"allow_assign_grafana_admin": "true",
"teams_url": "https://example.com/teams",
"auth_url": "https://example.com/auth",
"token_url": "https://example.com/token",
"login_prompt": "invalid",
},
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
}
for _, tc := range testCases {
@ -1269,6 +1283,7 @@ func TestSocialGenericOAuth_Reload(t *testing.T) {
"client_id": "new-client-id",
"client_secret": "new-client-secret",
"auth_url": "some-new-url",
"login_prompt": "login",
},
},
expectError: false,
@ -1276,6 +1291,7 @@ func TestSocialGenericOAuth_Reload(t *testing.T) {
ClientId: "new-client-id",
ClientSecret: "new-client-secret",
AuthUrl: "some-new-url",
LoginPrompt: "login",
},
expectedConfig: &oauth2.Config{
ClientID: "new-client-id",
@ -1357,6 +1373,7 @@ func TestGenericOAuth_Reload_ExtraFields(t *testing.T) {
EmailAttributeName: "email-attr-name",
GroupsAttributePath: "groups-attr-path",
TeamIdsAttributePath: "team-ids-attr-path",
LoginPrompt: "login",
Extra: map[string]string{
teamIdsKey: "team1",
allowedOrganizationsKey: "org1",
@ -1374,6 +1391,7 @@ func TestGenericOAuth_Reload_ExtraFields(t *testing.T) {
"email_attribute_name": "new-email-attr-name",
"groups_attribute_path": "new-group-attr-path",
"team_ids_attribute_path": "new-team-ids-attr-path",
"login_prompt": "select_account",
teamIdsKey: "team1,team2",
allowedOrganizationsKey: "org1,org2",
loginAttributePathKey: "new-login-attr-path",
@ -1389,6 +1407,7 @@ func TestGenericOAuth_Reload_ExtraFields(t *testing.T) {
EmailAttributeName: "new-email-attr-name",
GroupsAttributePath: "new-group-attr-path",
TeamIdsAttributePath: "new-team-ids-attr-path",
LoginPrompt: "select_account",
Extra: map[string]string{
teamIdsKey: "team1,team2",
allowedOrganizationsKey: "org1,org2",

@ -495,6 +495,7 @@ func TestSocialGitHub_Validate(t *testing.T) {
"auth_url": "",
"token_url": "",
"api_url": "",
"login_prompt": "select_account",
},
},
requester: &user.SignedInUser{IsGrafanaAdmin: true},
@ -594,6 +595,17 @@ func TestSocialGitHub_Validate(t *testing.T) {
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
{
name: "fails if login prompt is invalid",
settings: ssoModels.SSOSettings{
Settings: map[string]any{
"client_id": "client-id",
"allow_assign_grafana_admin": "true",
"login_prompt": "invalid",
},
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
}
for _, tc := range testCases {
@ -634,6 +646,7 @@ func TestSocialGitHub_Reload(t *testing.T) {
"client_id": "new-client-id",
"client_secret": "new-client-secret",
"auth_url": "some-new-url",
"login_prompt": "login",
},
},
expectError: false,
@ -641,6 +654,7 @@ func TestSocialGitHub_Reload(t *testing.T) {
ClientId: "new-client-id",
ClientSecret: "new-client-secret",
AuthUrl: "some-new-url",
LoginPrompt: "login",
},
expectedConfig: &oauth2.Config{
ClientID: "new-client-id",

@ -547,6 +547,7 @@ func TestSocialGitlab_Validate(t *testing.T) {
"auth_url": "",
"token_url": "",
"api_url": "",
"login_prompt": "select_account",
},
},
requester: &user.SignedInUser{IsGrafanaAdmin: true},
@ -640,6 +641,17 @@ func TestSocialGitlab_Validate(t *testing.T) {
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
{
name: "fails if login prompt is invalid",
settings: ssoModels.SSOSettings{
Settings: map[string]any{
"client_id": "client-id",
"allow_assign_grafana_admin": "true",
"login_prompt": "invalid",
},
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
}
for _, tc := range testCases {
@ -680,6 +692,7 @@ func TestSocialGitlab_Reload(t *testing.T) {
"client_id": "new-client-id",
"client_secret": "new-client-secret",
"auth_url": "some-new-url",
"login_prompt": "login",
},
},
expectError: false,
@ -687,6 +700,7 @@ func TestSocialGitlab_Reload(t *testing.T) {
ClientId: "new-client-id",
ClientSecret: "new-client-secret",
AuthUrl: "some-new-url",
LoginPrompt: "login",
},
expectedConfig: &oauth2.Config{
ClientID: "new-client-id",

@ -224,7 +224,8 @@ func (s *SocialGoogle) AuthCodeURL(state string, opts ...oauth2.AuthCodeOption)
if s.info.UseRefreshToken {
opts = append(opts, oauth2.AccessTypeOffline, oauth2.ApprovalForce)
}
return s.Config.AuthCodeURL(state, opts...)
return s.getAuthCodeURL(state, opts...)
}
func (s *SocialGoogle) extractFromToken(_ context.Context, _ *http.Client, token *oauth2.Token) (*googleUserData, error) {

@ -724,6 +724,7 @@ func TestSocialGoogle_Validate(t *testing.T) {
"auth_url": "",
"token_url": "",
"api_url": "",
"login_prompt": "select_account",
},
},
requester: &user.SignedInUser{IsGrafanaAdmin: true},
@ -830,6 +831,17 @@ func TestSocialGoogle_Validate(t *testing.T) {
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
{
name: "fails if login prompt is invalid",
settings: ssoModels.SSOSettings{
Settings: map[string]any{
"client_id": "client-id",
"allow_assign_grafana_admin": "true",
"login_prompt": "invalid",
},
},
wantErr: ssosettings.ErrBaseInvalidOAuthConfig,
},
}
for _, tc := range testCases {
@ -870,6 +882,7 @@ func TestSocialGoogle_Reload(t *testing.T) {
"client_id": "new-client-id",
"client_secret": "new-client-secret",
"auth_url": "some-new-url",
"login_prompt": "login",
},
},
expectError: false,
@ -877,6 +890,7 @@ func TestSocialGoogle_Reload(t *testing.T) {
ClientId: "new-client-id",
ClientSecret: "new-client-secret",
AuthUrl: "some-new-url",
LoginPrompt: "login",
},
expectedConfig: &oauth2.Config{
ClientID: "new-client-id",

@ -85,6 +85,15 @@ func (s *SocialBase) AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) st
s.reloadMutex.RLock()
defer s.reloadMutex.RUnlock()
return s.getAuthCodeURL(state, opts...)
}
func (s *SocialBase) getAuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string {
if s.info.LoginPrompt != "" {
promptOpt := oauth2.SetAuthURLParam("prompt", s.info.LoginPrompt)
opts = append(opts, promptOpt)
}
return s.Config.AuthCodeURL(state, opts...)
}
@ -268,5 +277,7 @@ func validateInfo(info *social.OAuthInfo, oldInfo *social.OAuthInfo, requester i
validation.AllowAssignGrafanaAdminValidator(info, oldInfo, requester),
validation.SkipOrgRoleSyncAllowAssignGrafanaAdminValidator,
validation.OrgAttributePathValidator(info, oldInfo, requester),
validation.OrgMappingValidator(info, oldInfo, requester))
validation.OrgMappingValidator(info, oldInfo, requester),
validation.LoginPromptValidator,
)
}

@ -99,6 +99,7 @@ type OAuthInfo struct {
TokenUrl string `mapstructure:"token_url" toml:"token_url"`
UsePKCE bool `mapstructure:"use_pkce" toml:"use_pkce"`
UseRefreshToken bool `mapstructure:"use_refresh_token" toml:"use_refresh_token"`
LoginPrompt string `mapstructure:"login_prompt" toml:"login_prompt"`
Extra map[string]string `mapstructure:",remain" toml:"extra,omitempty"`
}

@ -108,6 +108,7 @@ func (s *OAuthStrategy) loadSettingsForProvider(provider string) map[string]any
"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(),
"login_prompt": section.Key("login_prompt").Value(),
}
extraKeys := extraKeysByProvider[provider]

@ -58,6 +58,7 @@ var (
signout_redirect_url = test_signout_redirect_url
org_attribute_path = groups
org_mapping = Group1:*:Editor
login_prompt = select_account
`
expectedOAuthInfo = map[string]any{
@ -104,6 +105,7 @@ var (
"team_ids": "first, second",
"org_attribute_path": "groups",
"org_mapping": "Group1:*:Editor",
"login_prompt": "select_account",
}
)

@ -51,6 +51,15 @@ func SkipOrgRoleSyncAllowAssignGrafanaAdminValidator(info *social.OAuthInfo, req
return nil
}
func LoginPromptValidator(info *social.OAuthInfo, requester identity.Requester) error {
prompt := info.LoginPrompt
if prompt != "" && prompt != "login" && prompt != "consent" && prompt != "select_account" {
return ssosettings.ErrInvalidOAuthConfig("Invalid value for login_prompt. Valid values are: login, consent, select_account.")
}
return nil
}
func RequiredValidator(value string, name string) ssosettings.ValidateFunc[social.OAuthInfo] {
return func(info *social.OAuthInfo, requester identity.Requester) error {
if value == "" {

@ -154,6 +154,7 @@ describe('ProviderConfigForm', () => {
clientId: 'test-client-id',
clientSecret: 'test-client-secret',
enabled: true,
loginPrompt: '',
name: 'GitHub',
orgMapping: '["Group A:1:Editor","Group B:2:Admin"]',
roleAttributePath: 'new-attribute-path',
@ -204,6 +205,7 @@ describe('ProviderConfigForm', () => {
clientId: 'test-client-id',
clientSecret: 'test-client-secret',
enabled: false,
loginPrompt: '',
name: 'GitHub',
roleAttributePath: '',
roleAttributeStrict: false,

@ -44,6 +44,7 @@ export const getSectionFields = (): Section => {
'allowSignUp',
'autoLogin',
'signoutRedirectUrl',
'loginPrompt',
],
},
{
@ -87,6 +88,7 @@ export const getSectionFields = (): Section => {
'allowSignUp',
'autoLogin',
'signoutRedirectUrl',
'loginPrompt',
],
},
{
@ -132,7 +134,16 @@ export const getSectionFields = (): Section => {
{
name: generalSettingsLabel,
id: 'general',
fields: ['name', 'clientId', 'clientSecret', 'scopes', 'allowSignUp', 'autoLogin', 'signoutRedirectUrl'],
fields: [
'name',
'clientId',
'clientSecret',
'scopes',
'allowSignUp',
'autoLogin',
'signoutRedirectUrl',
'loginPrompt',
],
},
{
name: userMappingLabel,
@ -166,7 +177,16 @@ export const getSectionFields = (): Section => {
{
name: generalSettingsLabel,
id: 'general',
fields: ['name', 'clientId', 'clientSecret', 'scopes', 'allowSignUp', 'autoLogin', 'signoutRedirectUrl'],
fields: [
'name',
'clientId',
'clientSecret',
'scopes',
'allowSignUp',
'autoLogin',
'signoutRedirectUrl',
'loginPrompt',
],
},
{
name: userMappingLabel,
@ -199,7 +219,16 @@ export const getSectionFields = (): Section => {
{
name: generalSettingsLabel,
id: 'general',
fields: ['name', 'clientId', 'clientSecret', 'scopes', 'allowSignUp', 'autoLogin', 'signoutRedirectUrl'],
fields: [
'name',
'clientId',
'clientSecret',
'scopes',
'allowSignUp',
'autoLogin',
'signoutRedirectUrl',
'loginPrompt',
],
},
{
name: userMappingLabel,
@ -890,6 +919,22 @@ export function fieldMap(provider: string): Record<string, FieldData> {
message: t('auth-config.fields.domain-hint-valid-domain', 'This field must be a valid domain.'),
},
},
loginPrompt: {
label: t('auth-config.fields.login-prompt-label', 'Login prompt'),
type: 'select',
description: t(
'auth-config.fields.login-prompt-description',
'Indicates the type of user interaction when the user logs in with the IdP.'
),
multi: false,
options: [
{ value: '', label: '' },
{ value: 'login', label: t('auth-config.fields.login-prompt-login', 'Login') },
{ value: 'consent', label: t('auth-config.fields.login-prompt-consent', 'Consent') },
{ value: 'select_account', label: t('auth-config.fields.login-prompt-select-account', 'Select account') },
],
defaultValue: { value: '', label: '' },
},
};
}

@ -61,6 +61,7 @@ export type SSOProviderSettingsBase = {
// For Azure AD
forceUseGraphApi?: boolean;
domainHint?: string;
loginPrompt?: string;
// For Google
validateHd?: boolean;
};

@ -25,6 +25,7 @@ export const emptySettings: SSOProviderDTO = {
emailAttributePath: '',
emptyScopes: false,
enabled: false,
loginPrompt: '',
extra: {},
groupsAttributePath: '',
hostedDomain: '',

@ -3256,6 +3256,11 @@
"id-token-attribute-name-label": "ID token attribute name",
"login-attribute-path-description": "JMESPath expression to use for user login lookup from the user ID token.",
"login-attribute-path-label": "Login attribute path",
"login-prompt-consent": "Consent",
"login-prompt-description": "Indicates the type of user interaction when the user logs in with the IdP.",
"login-prompt-label": "Login prompt",
"login-prompt-login": "Login",
"login-prompt-select-account": "Select account",
"managed-identity-client-id-description": "The managed identity client ID of the federated identity credential of your OAuth2 app.",
"managed-identity-client-id-label": "FIC managed identity client ID",
"name-attribute-path-description": "JMESPath expression to use for user name lookup from the user ID token. \nThis name will be used as the user's display name.",

Loading…
Cancel
Save