17335: Configurable auth params for OIDC and Google.
authorTom Clegg <tom@curii.com>
Thu, 4 Feb 2021 17:11:02 +0000 (12:11 -0500)
committerTom Clegg <tom@curii.com>
Thu, 4 Feb 2021 17:11:02 +0000 (12:11 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

lib/config/config.default.yml
lib/config/export.go
lib/config/generated_config.go
lib/controller/localdb/login.go
lib/controller/localdb/login_oidc.go
lib/controller/localdb/login_oidc_test.go
sdk/go/arvados/config.go

index 771dc2ee799584e4853c5e59c1769bd46bf44509..3f478306584e5029be1d70fec11a200d98dd0b55 100644 (file)
@@ -567,6 +567,17 @@ Clusters:
         # work. If false, only the primary email address will be used.
         AlternateEmailAddresses: true
 
+        # Send additional parameters with authentication requests. See
+        # https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters
+        # for a list of supported parameters.
+        AuthenticationRequestParameters:
+          # Show the "choose which Google account" page, even if the
+          # client is currently logged in to exactly one Google
+          # account.
+          prompt: select_account
+
+          SAMPLE: ""
+
       OpenIDConnect:
         # Authenticate with an OpenID Connect provider.
         Enable: false
@@ -601,6 +612,14 @@ Clusters:
         # address.
         UsernameClaim: ""
 
+        # Send additional parameters with authentication requests,
+        # like {display: page, prompt: consent}. See
+        # https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
+        # and refer to your provider's documentation for supported
+        # parameters.
+        AuthenticationRequestParameters:
+          SAMPLE: ""
+
       PAM:
         # (Experimental) Use PAM to authenticate users.
         Enable: false
index e4917032ffe06ca72d5a016fe7cd747a4cc12e02..2dbb11bba3f27a4c073776b8e302a6ff69d71f21 100644 (file)
@@ -59,208 +59,210 @@ func ExportJSON(w io.Writer, cluster *arvados.Cluster) error {
 // exists.
 var whitelist = map[string]bool{
        // | sort -t'"' -k2,2
-       "API":                                          true,
-       "API.AsyncPermissionsUpdateInterval":           false,
-       "API.DisabledAPIs":                             false,
-       "API.KeepServiceRequestTimeout":                false,
-       "API.MaxConcurrentRequests":                    false,
-       "API.MaxIndexDatabaseRead":                     false,
-       "API.MaxItemsPerResponse":                      true,
-       "API.MaxKeepBlobBuffers":                       false,
-       "API.MaxRequestAmplification":                  false,
-       "API.MaxRequestSize":                           true,
-       "API.RequestTimeout":                           true,
-       "API.SendTimeout":                              true,
-       "API.WebsocketClientEventQueue":                false,
-       "API.WebsocketServerEventQueue":                false,
-       "AuditLogs":                                    false,
-       "AuditLogs.MaxAge":                             false,
-       "AuditLogs.MaxDeleteBatch":                     false,
-       "AuditLogs.UnloggedAttributes":                 false,
-       "ClusterID":                                    true,
-       "Collections":                                  true,
-       "Collections.BalanceCollectionBatch":           false,
-       "Collections.BalanceCollectionBuffers":         false,
-       "Collections.BalancePeriod":                    false,
-       "Collections.BalanceTimeout":                   false,
-       "Collections.BlobDeleteConcurrency":            false,
-       "Collections.BlobMissingReport":                false,
-       "Collections.BlobReplicateConcurrency":         false,
-       "Collections.BlobSigning":                      true,
-       "Collections.BlobSigningKey":                   false,
-       "Collections.BlobSigningTTL":                   true,
-       "Collections.BlobTrash":                        false,
-       "Collections.BlobTrashCheckInterval":           false,
-       "Collections.BlobTrashConcurrency":             false,
-       "Collections.BlobTrashLifetime":                false,
-       "Collections.CollectionVersioning":             false,
-       "Collections.DefaultReplication":               true,
-       "Collections.DefaultTrashLifetime":             true,
-       "Collections.ForwardSlashNameSubstitution":     true,
-       "Collections.ManagedProperties":                true,
-       "Collections.ManagedProperties.*":              true,
-       "Collections.ManagedProperties.*.*":            true,
-       "Collections.PreserveVersionIfIdle":            true,
-       "Collections.S3FolderObjects":                  true,
-       "Collections.TrashSweepInterval":               false,
-       "Collections.TrustAllContent":                  false,
-       "Collections.WebDAVCache":                      false,
-       "Containers":                                   true,
-       "Containers.CloudVMs":                          false,
-       "Containers.CrunchRunArgumentsList":            false,
-       "Containers.CrunchRunCommand":                  false,
-       "Containers.DefaultKeepCacheRAM":               true,
-       "Containers.DispatchPrivateKey":                false,
-       "Containers.JobsAPI":                           true,
-       "Containers.JobsAPI.Enable":                    true,
-       "Containers.JobsAPI.GitInternalDir":            false,
-       "Containers.Logging":                           false,
-       "Containers.LogReuseDecisions":                 false,
-       "Containers.MaxComputeVMs":                     false,
-       "Containers.MaxDispatchAttempts":               false,
-       "Containers.MaxRetryAttempts":                  true,
-       "Containers.MinRetryPeriod":                    true,
-       "Containers.ReserveExtraRAM":                   true,
-       "Containers.SLURM":                             false,
-       "Containers.StaleLockTimeout":                  false,
-       "Containers.SupportedDockerImageFormats":       true,
-       "Containers.SupportedDockerImageFormats.*":     true,
-       "Containers.UsePreemptibleInstances":           true,
-       "ForceLegacyAPI14":                             false,
-       "Git":                                          false,
-       "InstanceTypes":                                true,
-       "InstanceTypes.*":                              true,
-       "InstanceTypes.*.*":                            true,
-       "Login":                                        true,
-       "Login.Google":                                 true,
-       "Login.Google.AlternateEmailAddresses":         false,
-       "Login.Google.ClientID":                        false,
-       "Login.Google.ClientSecret":                    false,
-       "Login.Google.Enable":                          true,
-       "Login.LDAP":                                   true,
-       "Login.LDAP.AppendDomain":                      false,
-       "Login.LDAP.EmailAttribute":                    false,
-       "Login.LDAP.Enable":                            true,
-       "Login.LDAP.InsecureTLS":                       false,
-       "Login.LDAP.SearchAttribute":                   false,
-       "Login.LDAP.SearchBase":                        false,
-       "Login.LDAP.SearchBindPassword":                false,
-       "Login.LDAP.SearchBindUser":                    false,
-       "Login.LDAP.SearchFilters":                     false,
-       "Login.LDAP.StartTLS":                          false,
-       "Login.LDAP.StripDomain":                       false,
-       "Login.LDAP.URL":                               false,
-       "Login.LDAP.UsernameAttribute":                 false,
-       "Login.LoginCluster":                           true,
-       "Login.OpenIDConnect":                          true,
-       "Login.OpenIDConnect.ClientID":                 false,
-       "Login.OpenIDConnect.ClientSecret":             false,
-       "Login.OpenIDConnect.EmailClaim":               false,
-       "Login.OpenIDConnect.EmailVerifiedClaim":       false,
-       "Login.OpenIDConnect.Enable":                   true,
-       "Login.OpenIDConnect.Issuer":                   false,
-       "Login.OpenIDConnect.UsernameClaim":            false,
-       "Login.PAM":                                    true,
-       "Login.PAM.DefaultEmailDomain":                 false,
-       "Login.PAM.Enable":                             true,
-       "Login.PAM.Service":                            false,
-       "Login.RemoteTokenRefresh":                     true,
-       "Login.SSO":                                    true,
-       "Login.SSO.Enable":                             true,
-       "Login.SSO.ProviderAppID":                      false,
-       "Login.SSO.ProviderAppSecret":                  false,
-       "Login.Test":                                   true,
-       "Login.Test.Enable":                            true,
-       "Login.Test.Users":                             false,
-       "Login.TokenLifetime":                          false,
-       "Login.TrustedClients":                         false,
-       "Mail":                                         true,
-       "Mail.EmailFrom":                               false,
-       "Mail.IssueReporterEmailFrom":                  false,
-       "Mail.IssueReporterEmailTo":                    false,
-       "Mail.MailchimpAPIKey":                         false,
-       "Mail.MailchimpListID":                         false,
-       "Mail.SendUserSetupNotificationEmail":          false,
-       "Mail.SupportEmailAddress":                     true,
-       "ManagementToken":                              false,
-       "PostgreSQL":                                   false,
-       "RemoteClusters":                               true,
-       "RemoteClusters.*":                             true,
-       "RemoteClusters.*.ActivateUsers":               true,
-       "RemoteClusters.*.Host":                        true,
-       "RemoteClusters.*.Insecure":                    true,
-       "RemoteClusters.*.Proxy":                       true,
-       "RemoteClusters.*.Scheme":                      true,
-       "Services":                                     true,
-       "Services.*":                                   true,
-       "Services.*.ExternalURL":                       true,
-       "Services.*.InternalURLs":                      false,
-       "SystemLogs":                                   false,
-       "SystemRootToken":                              false,
-       "TLS":                                          false,
-       "Users":                                        true,
-       "Users.AdminNotifierEmailFrom":                 false,
-       "Users.AnonymousUserToken":                     true,
-       "Users.AutoAdminFirstUser":                     false,
-       "Users.AutoAdminUserWithEmail":                 false,
-       "Users.AutoSetupNewUsers":                      false,
-       "Users.AutoSetupNewUsersWithRepository":        false,
-       "Users.AutoSetupNewUsersWithVmUUID":            false,
-       "Users.AutoSetupUsernameBlacklist":             false,
-       "Users.EmailSubjectPrefix":                     false,
-       "Users.NewInactiveUserNotificationRecipients":  false,
-       "Users.NewUserNotificationRecipients":          false,
-       "Users.NewUsersAreActive":                      false,
-       "Users.PreferDomainForUsername":                false,
-       "Users.UserNotifierEmailFrom":                  false,
-       "Users.UserProfileNotificationAddress":         false,
-       "Users.UserSetupMailText":                      false,
-       "Volumes":                                      true,
-       "Volumes.*":                                    true,
-       "Volumes.*.*":                                  false,
-       "Volumes.*.AccessViaHosts":                     true,
-       "Volumes.*.AccessViaHosts.*":                   true,
-       "Volumes.*.AccessViaHosts.*.ReadOnly":          true,
-       "Volumes.*.ReadOnly":                           true,
-       "Volumes.*.Replication":                        true,
-       "Volumes.*.StorageClasses":                     true,
-       "Volumes.*.StorageClasses.*":                   false,
-       "Workbench":                                    true,
-       "Workbench.ActivationContactLink":              false,
-       "Workbench.APIClientConnectTimeout":            true,
-       "Workbench.APIClientReceiveTimeout":            true,
-       "Workbench.APIResponseCompression":             true,
-       "Workbench.ApplicationMimetypesWithViewIcon":   true,
-       "Workbench.ApplicationMimetypesWithViewIcon.*": true,
-       "Workbench.ArvadosDocsite":                     true,
-       "Workbench.ArvadosPublicDataDocURL":            true,
-       "Workbench.DefaultOpenIdPrefix":                false,
-       "Workbench.EnableGettingStartedPopup":          true,
-       "Workbench.EnablePublicProjectsPage":           true,
-       "Workbench.FileViewersConfigURL":               true,
-       "Workbench.IdleTimeout":                        true,
-       "Workbench.InactivePageHTML":                   true,
-       "Workbench.LogViewerMaxBytes":                  true,
-       "Workbench.MultiSiteSearch":                    true,
-       "Workbench.ProfilingEnabled":                   true,
-       "Workbench.Repositories":                       false,
-       "Workbench.RepositoryCache":                    false,
-       "Workbench.RunningJobLogRecordsToFetch":        true,
-       "Workbench.SecretKeyBase":                      false,
-       "Workbench.ShowRecentCollectionsOnDashboard":   true,
-       "Workbench.ShowUserAgreementInline":            true,
-       "Workbench.ShowUserNotifications":              true,
-       "Workbench.SiteName":                           true,
-       "Workbench.SSHHelpHostSuffix":                  true,
-       "Workbench.SSHHelpPageHTML":                    true,
-       "Workbench.Theme":                              true,
-       "Workbench.UserProfileFormFields":              true,
-       "Workbench.UserProfileFormFields.*":            true,
-       "Workbench.UserProfileFormFields.*.*":          true,
-       "Workbench.UserProfileFormFields.*.*.*":        true,
-       "Workbench.UserProfileFormMessage":             true,
-       "Workbench.VocabularyURL":                      true,
-       "Workbench.WelcomePageHTML":                    true,
+       "API":                                                 true,
+       "API.AsyncPermissionsUpdateInterval":                  false,
+       "API.DisabledAPIs":                                    false,
+       "API.KeepServiceRequestTimeout":                       false,
+       "API.MaxConcurrentRequests":                           false,
+       "API.MaxIndexDatabaseRead":                            false,
+       "API.MaxItemsPerResponse":                             true,
+       "API.MaxKeepBlobBuffers":                              false,
+       "API.MaxRequestAmplification":                         false,
+       "API.MaxRequestSize":                                  true,
+       "API.RequestTimeout":                                  true,
+       "API.SendTimeout":                                     true,
+       "API.WebsocketClientEventQueue":                       false,
+       "API.WebsocketServerEventQueue":                       false,
+       "AuditLogs":                                           false,
+       "AuditLogs.MaxAge":                                    false,
+       "AuditLogs.MaxDeleteBatch":                            false,
+       "AuditLogs.UnloggedAttributes":                        false,
+       "ClusterID":                                           true,
+       "Collections":                                         true,
+       "Collections.BalanceCollectionBatch":                  false,
+       "Collections.BalanceCollectionBuffers":                false,
+       "Collections.BalancePeriod":                           false,
+       "Collections.BalanceTimeout":                          false,
+       "Collections.BlobDeleteConcurrency":                   false,
+       "Collections.BlobMissingReport":                       false,
+       "Collections.BlobReplicateConcurrency":                false,
+       "Collections.BlobSigning":                             true,
+       "Collections.BlobSigningKey":                          false,
+       "Collections.BlobSigningTTL":                          true,
+       "Collections.BlobTrash":                               false,
+       "Collections.BlobTrashCheckInterval":                  false,
+       "Collections.BlobTrashConcurrency":                    false,
+       "Collections.BlobTrashLifetime":                       false,
+       "Collections.CollectionVersioning":                    false,
+       "Collections.DefaultReplication":                      true,
+       "Collections.DefaultTrashLifetime":                    true,
+       "Collections.ForwardSlashNameSubstitution":            true,
+       "Collections.ManagedProperties":                       true,
+       "Collections.ManagedProperties.*":                     true,
+       "Collections.ManagedProperties.*.*":                   true,
+       "Collections.PreserveVersionIfIdle":                   true,
+       "Collections.S3FolderObjects":                         true,
+       "Collections.TrashSweepInterval":                      false,
+       "Collections.TrustAllContent":                         false,
+       "Collections.WebDAVCache":                             false,
+       "Containers":                                          true,
+       "Containers.CloudVMs":                                 false,
+       "Containers.CrunchRunArgumentsList":                   false,
+       "Containers.CrunchRunCommand":                         false,
+       "Containers.DefaultKeepCacheRAM":                      true,
+       "Containers.DispatchPrivateKey":                       false,
+       "Containers.JobsAPI":                                  true,
+       "Containers.JobsAPI.Enable":                           true,
+       "Containers.JobsAPI.GitInternalDir":                   false,
+       "Containers.Logging":                                  false,
+       "Containers.LogReuseDecisions":                        false,
+       "Containers.MaxComputeVMs":                            false,
+       "Containers.MaxDispatchAttempts":                      false,
+       "Containers.MaxRetryAttempts":                         true,
+       "Containers.MinRetryPeriod":                           true,
+       "Containers.ReserveExtraRAM":                          true,
+       "Containers.SLURM":                                    false,
+       "Containers.StaleLockTimeout":                         false,
+       "Containers.SupportedDockerImageFormats":              true,
+       "Containers.SupportedDockerImageFormats.*":            true,
+       "Containers.UsePreemptibleInstances":                  true,
+       "ForceLegacyAPI14":                                    false,
+       "Git":                                                 false,
+       "InstanceTypes":                                       true,
+       "InstanceTypes.*":                                     true,
+       "InstanceTypes.*.*":                                   true,
+       "Login":                                               true,
+       "Login.Google":                                        true,
+       "Login.Google.AlternateEmailAddresses":                false,
+       "Login.Google.AuthenticationRequestParameters":        false,
+       "Login.Google.ClientID":                               false,
+       "Login.Google.ClientSecret":                           false,
+       "Login.Google.Enable":                                 true,
+       "Login.LDAP":                                          true,
+       "Login.LDAP.AppendDomain":                             false,
+       "Login.LDAP.EmailAttribute":                           false,
+       "Login.LDAP.Enable":                                   true,
+       "Login.LDAP.InsecureTLS":                              false,
+       "Login.LDAP.SearchAttribute":                          false,
+       "Login.LDAP.SearchBase":                               false,
+       "Login.LDAP.SearchBindPassword":                       false,
+       "Login.LDAP.SearchBindUser":                           false,
+       "Login.LDAP.SearchFilters":                            false,
+       "Login.LDAP.StartTLS":                                 false,
+       "Login.LDAP.StripDomain":                              false,
+       "Login.LDAP.URL":                                      false,
+       "Login.LDAP.UsernameAttribute":                        false,
+       "Login.LoginCluster":                                  true,
+       "Login.OpenIDConnect":                                 true,
+       "Login.OpenIDConnect.AuthenticationRequestParameters": false,
+       "Login.OpenIDConnect.ClientID":                        false,
+       "Login.OpenIDConnect.ClientSecret":                    false,
+       "Login.OpenIDConnect.EmailClaim":                      false,
+       "Login.OpenIDConnect.EmailVerifiedClaim":              false,
+       "Login.OpenIDConnect.Enable":                          true,
+       "Login.OpenIDConnect.Issuer":                          false,
+       "Login.OpenIDConnect.UsernameClaim":                   false,
+       "Login.PAM":                                           true,
+       "Login.PAM.DefaultEmailDomain":                        false,
+       "Login.PAM.Enable":                                    true,
+       "Login.PAM.Service":                                   false,
+       "Login.RemoteTokenRefresh":                            true,
+       "Login.SSO":                                           true,
+       "Login.SSO.Enable":                                    true,
+       "Login.SSO.ProviderAppID":                             false,
+       "Login.SSO.ProviderAppSecret":                         false,
+       "Login.Test":                                          true,
+       "Login.Test.Enable":                                   true,
+       "Login.Test.Users":                                    false,
+       "Login.TokenLifetime":                                 false,
+       "Login.TrustedClients":                                false,
+       "Mail":                                                true,
+       "Mail.EmailFrom":                                      false,
+       "Mail.IssueReporterEmailFrom":                         false,
+       "Mail.IssueReporterEmailTo":                           false,
+       "Mail.MailchimpAPIKey":                                false,
+       "Mail.MailchimpListID":                                false,
+       "Mail.SendUserSetupNotificationEmail":                 false,
+       "Mail.SupportEmailAddress":                            true,
+       "ManagementToken":                                     false,
+       "PostgreSQL":                                          false,
+       "RemoteClusters":                                      true,
+       "RemoteClusters.*":                                    true,
+       "RemoteClusters.*.ActivateUsers":                      true,
+       "RemoteClusters.*.Host":                               true,
+       "RemoteClusters.*.Insecure":                           true,
+       "RemoteClusters.*.Proxy":                              true,
+       "RemoteClusters.*.Scheme":                             true,
+       "Services":                                            true,
+       "Services.*":                                          true,
+       "Services.*.ExternalURL":                              true,
+       "Services.*.InternalURLs":                             false,
+       "SystemLogs":                                          false,
+       "SystemRootToken":                                     false,
+       "TLS":                                                 false,
+       "Users":                                               true,
+       "Users.AdminNotifierEmailFrom":                        false,
+       "Users.AnonymousUserToken":                            true,
+       "Users.AutoAdminFirstUser":                            false,
+       "Users.AutoAdminUserWithEmail":                        false,
+       "Users.AutoSetupNewUsers":                             false,
+       "Users.AutoSetupNewUsersWithRepository":               false,
+       "Users.AutoSetupNewUsersWithVmUUID":                   false,
+       "Users.AutoSetupUsernameBlacklist":                    false,
+       "Users.EmailSubjectPrefix":                            false,
+       "Users.NewInactiveUserNotificationRecipients":         false,
+       "Users.NewUserNotificationRecipients":                 false,
+       "Users.NewUsersAreActive":                             false,
+       "Users.PreferDomainForUsername":                       false,
+       "Users.UserNotifierEmailFrom":                         false,
+       "Users.UserProfileNotificationAddress":                false,
+       "Users.UserSetupMailText":                             false,
+       "Volumes":                                             true,
+       "Volumes.*":                                           true,
+       "Volumes.*.*":                                         false,
+       "Volumes.*.AccessViaHosts":                            true,
+       "Volumes.*.AccessViaHosts.*":                          true,
+       "Volumes.*.AccessViaHosts.*.ReadOnly":                 true,
+       "Volumes.*.ReadOnly":                                  true,
+       "Volumes.*.Replication":                               true,
+       "Volumes.*.StorageClasses":                            true,
+       "Volumes.*.StorageClasses.*":                          false,
+       "Workbench":                                           true,
+       "Workbench.ActivationContactLink":                     false,
+       "Workbench.APIClientConnectTimeout":                   true,
+       "Workbench.APIClientReceiveTimeout":                   true,
+       "Workbench.APIResponseCompression":                    true,
+       "Workbench.ApplicationMimetypesWithViewIcon":          true,
+       "Workbench.ApplicationMimetypesWithViewIcon.*":        true,
+       "Workbench.ArvadosDocsite":                            true,
+       "Workbench.ArvadosPublicDataDocURL":                   true,
+       "Workbench.DefaultOpenIdPrefix":                       false,
+       "Workbench.EnableGettingStartedPopup":                 true,
+       "Workbench.EnablePublicProjectsPage":                  true,
+       "Workbench.FileViewersConfigURL":                      true,
+       "Workbench.IdleTimeout":                               true,
+       "Workbench.InactivePageHTML":                          true,
+       "Workbench.LogViewerMaxBytes":                         true,
+       "Workbench.MultiSiteSearch":                           true,
+       "Workbench.ProfilingEnabled":                          true,
+       "Workbench.Repositories":                              false,
+       "Workbench.RepositoryCache":                           false,
+       "Workbench.RunningJobLogRecordsToFetch":               true,
+       "Workbench.SecretKeyBase":                             false,
+       "Workbench.ShowRecentCollectionsOnDashboard":          true,
+       "Workbench.ShowUserAgreementInline":                   true,
+       "Workbench.ShowUserNotifications":                     true,
+       "Workbench.SiteName":                                  true,
+       "Workbench.SSHHelpHostSuffix":                         true,
+       "Workbench.SSHHelpPageHTML":                           true,
+       "Workbench.Theme":                                     true,
+       "Workbench.UserProfileFormFields":                     true,
+       "Workbench.UserProfileFormFields.*":                   true,
+       "Workbench.UserProfileFormFields.*.*":                 true,
+       "Workbench.UserProfileFormFields.*.*.*":               true,
+       "Workbench.UserProfileFormMessage":                    true,
+       "Workbench.VocabularyURL":                             true,
+       "Workbench.WelcomePageHTML":                           true,
 }
 
 func redactUnsafe(m map[string]interface{}, mPrefix, lookupPrefix string) error {
index a202a540476ed54a36097244005c24822503ccf2..64dbf41209a57288dc04c6ef164cdbca318af45c 100644 (file)
@@ -573,6 +573,17 @@ Clusters:
         # work. If false, only the primary email address will be used.
         AlternateEmailAddresses: true
 
+        # Send additional parameters with authentication requests. See
+        # https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters
+        # for a list of supported parameters.
+        AuthenticationRequestParameters:
+          # Show the "choose which Google account" page, even if the
+          # client is currently logged in to exactly one Google
+          # account.
+          prompt: select_account
+
+          SAMPLE: ""
+
       OpenIDConnect:
         # Authenticate with an OpenID Connect provider.
         Enable: false
@@ -607,6 +618,14 @@ Clusters:
         # address.
         UsernameClaim: ""
 
+        # Send additional parameters with authentication requests,
+        # like {display: page, prompt: consent}. See
+        # https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
+        # and refer to your provider's documentation for supported
+        # parameters.
+        AuthenticationRequestParameters:
+          SAMPLE: ""
+
       PAM:
         # (Experimental) Use PAM to authenticate users.
         Enable: false
index 4bf515fc3f1113b6a240e991ecc3e236c8b49ee3..4e76b176d99a9c7846a3c0cae55c37e13c031573 100644 (file)
@@ -47,6 +47,7 @@ func chooseLoginController(cluster *arvados.Cluster, parent *Conn) loginControll
                        Issuer:             "https://accounts.google.com",
                        ClientID:           cluster.Login.Google.ClientID,
                        ClientSecret:       cluster.Login.Google.ClientSecret,
+                       AuthParams:         cluster.Login.Google.AuthenticationRequestParameters,
                        UseGooglePeopleAPI: cluster.Login.Google.AlternateEmailAddresses,
                        EmailClaim:         "email",
                        EmailVerifiedClaim: "email_verified",
@@ -58,6 +59,7 @@ func chooseLoginController(cluster *arvados.Cluster, parent *Conn) loginControll
                        Issuer:             cluster.Login.OpenIDConnect.Issuer,
                        ClientID:           cluster.Login.OpenIDConnect.ClientID,
                        ClientSecret:       cluster.Login.OpenIDConnect.ClientSecret,
+                       AuthParams:         cluster.Login.OpenIDConnect.AuthenticationRequestParameters,
                        EmailClaim:         cluster.Login.OpenIDConnect.EmailClaim,
                        EmailVerifiedClaim: cluster.Login.OpenIDConnect.EmailVerifiedClaim,
                        UsernameClaim:      cluster.Login.OpenIDConnect.UsernameClaim,
index a5fe45181b3319c0b07b881f747719762dcabb8a..2b67a95046620c00621de88017e29124e273b5a4 100644 (file)
@@ -50,10 +50,11 @@ type oidcLoginController struct {
        Issuer             string // OIDC issuer URL, e.g., "https://accounts.google.com"
        ClientID           string
        ClientSecret       string
-       UseGooglePeopleAPI bool   // Use Google People API to look up alternate email addresses
-       EmailClaim         string // OpenID claim to use as email address; typically "email"
-       EmailVerifiedClaim string // If non-empty, ensure claim value is true before accepting EmailClaim; typically "email_verified"
-       UsernameClaim      string // If non-empty, use as preferred username
+       UseGooglePeopleAPI bool              // Use Google People API to look up alternate email addresses
+       EmailClaim         string            // OpenID claim to use as email address; typically "email"
+       EmailVerifiedClaim string            // If non-empty, ensure claim value is true before accepting EmailClaim; typically "email_verified"
+       UsernameClaim      string            // If non-empty, use as preferred username
+       AuthParams         map[string]string // Additional parameters to pass with authentication request
 
        // override Google People API base URL for testing purposes
        // (normally empty, set by google pkg to
@@ -111,14 +112,12 @@ func (ctrl *oidcLoginController) Login(ctx context.Context, opts arvados.LoginOp
                        return loginError(errors.New("missing return_to parameter"))
                }
                state := ctrl.newOAuth2State([]byte(ctrl.Cluster.SystemRootToken), opts.Remote, opts.ReturnTo)
+               var authparams []oauth2.AuthCodeOption
+               for k, v := range ctrl.AuthParams {
+                       authparams = append(authparams, oauth2.SetAuthURLParam(k, v))
+               }
                return arvados.LoginResponse{
-                       RedirectLocation: ctrl.oauth2conf.AuthCodeURL(state.String(),
-                               // prompt=select_account tells Google
-                               // to show the "choose which Google
-                               // account" page, even if the client
-                               // is currently logged in to exactly
-                               // one Google account.
-                               oauth2.SetAuthURLParam("prompt", "select_account")),
+                       RedirectLocation: ctrl.oauth2conf.AuthCodeURL(state.String(), authparams...),
                }, nil
        }
        // Callback after OIDC sign-in.
index e157b73fc6d25ed158d25703e6e4bb961007932f..e3c72adddcdbbf76650fada2a8eb8401add88431 100644 (file)
@@ -165,12 +165,14 @@ func (s *OIDCLoginSuite) TestConfig(c *check.C) {
        s.cluster.Login.OpenIDConnect.Issuer = "https://accounts.example.com/"
        s.cluster.Login.OpenIDConnect.ClientID = "oidc-client-id"
        s.cluster.Login.OpenIDConnect.ClientSecret = "oidc-client-secret"
+       s.cluster.Login.OpenIDConnect.AuthenticationRequestParameters = map[string]string{"testkey": "testvalue"}
        localdb := NewConn(s.cluster)
        ctrl := localdb.loginController.(*oidcLoginController)
        c.Check(ctrl.Issuer, check.Equals, "https://accounts.example.com/")
        c.Check(ctrl.ClientID, check.Equals, "oidc-client-id")
        c.Check(ctrl.ClientSecret, check.Equals, "oidc-client-secret")
        c.Check(ctrl.UseGooglePeopleAPI, check.Equals, false)
+       c.Check(ctrl.AuthParams["testkey"], check.Equals, "testvalue")
 
        for _, enableAltEmails := range []bool{false, true} {
                s.cluster.Login.OpenIDConnect.Enable = false
@@ -178,12 +180,14 @@ func (s *OIDCLoginSuite) TestConfig(c *check.C) {
                s.cluster.Login.Google.ClientID = "google-client-id"
                s.cluster.Login.Google.ClientSecret = "google-client-secret"
                s.cluster.Login.Google.AlternateEmailAddresses = enableAltEmails
+               s.cluster.Login.Google.AuthenticationRequestParameters = map[string]string{"testkey": "testvalue"}
                localdb = NewConn(s.cluster)
                ctrl = localdb.loginController.(*oidcLoginController)
                c.Check(ctrl.Issuer, check.Equals, "https://accounts.google.com")
                c.Check(ctrl.ClientID, check.Equals, "google-client-id")
                c.Check(ctrl.ClientSecret, check.Equals, "google-client-secret")
                c.Check(ctrl.UseGooglePeopleAPI, check.Equals, enableAltEmails)
+               c.Check(ctrl.AuthParams["testkey"], check.Equals, "testvalue")
        }
 }
 
@@ -260,6 +264,7 @@ func (s *OIDCLoginSuite) TestGenericOIDCLogin(c *check.C) {
        json.Unmarshal([]byte(fmt.Sprintf("%q", s.fakeProvider.Issuer.URL)), &s.cluster.Login.OpenIDConnect.Issuer)
        s.cluster.Login.OpenIDConnect.ClientID = "oidc#client#id"
        s.cluster.Login.OpenIDConnect.ClientSecret = "oidc#client#secret"
+       s.cluster.Login.OpenIDConnect.AuthenticationRequestParameters = map[string]string{"testkey": "testvalue"}
        s.fakeProvider.ValidClientID = "oidc#client#id"
        s.fakeProvider.ValidClientSecret = "oidc#client#secret"
        for _, trial := range []struct {
@@ -319,7 +324,9 @@ func (s *OIDCLoginSuite) TestGenericOIDCLogin(c *check.C) {
                s.localdb = NewConn(s.cluster)
                *s.localdb.railsProxy = *rpc.NewConn(s.cluster.ClusterID, s.railsSpy.URL, true, rpc.PassthroughTokenProvider)
 
-               state := s.startLogin(c)
+               state := s.startLogin(c, func(form url.Values) {
+                       c.Check(form.Get("testkey"), check.Equals, "testvalue")
+               })
                resp, err := s.localdb.Login(context.Background(), arvados.LoginOptions{
                        Code:  s.fakeProvider.ValidCode,
                        State: state,
@@ -350,7 +357,12 @@ func (s *OIDCLoginSuite) TestGenericOIDCLogin(c *check.C) {
 }
 
 func (s *OIDCLoginSuite) TestGoogleLogin_Success(c *check.C) {
-       state := s.startLogin(c)
+       s.cluster.Login.Google.AuthenticationRequestParameters["prompt"] = "consent"
+       s.cluster.Login.Google.AuthenticationRequestParameters["foo"] = "bar"
+       state := s.startLogin(c, func(form url.Values) {
+               c.Check(form.Get("foo"), check.Equals, "bar")
+               c.Check(form.Get("prompt"), check.Equals, "consent")
+       })
        resp, err := s.localdb.Login(context.Background(), arvados.LoginOptions{
                Code:  s.fakeProvider.ValidCode,
                State: state,
@@ -515,7 +527,7 @@ func (s *OIDCLoginSuite) TestGoogleLogin_NoPrimaryEmailAddress(c *check.C) {
        c.Check(authinfo.Username, check.Equals, "")
 }
 
-func (s *OIDCLoginSuite) startLogin(c *check.C) (state string) {
+func (s *OIDCLoginSuite) startLogin(c *check.C, checks ...func(url.Values)) (state string) {
        // Initiate login, but instead of following the redirect to
        // the provider, just grab state from the redirect URL.
        resp, err := s.localdb.Login(context.Background(), arvados.LoginOptions{ReturnTo: "https://app.example.com/foo?bar"})
@@ -524,6 +536,10 @@ func (s *OIDCLoginSuite) startLogin(c *check.C) (state string) {
        c.Check(err, check.IsNil)
        state = target.Query().Get("state")
        c.Check(state, check.Not(check.Equals), "")
+       for _, fn := range checks {
+               fn(target.Query())
+       }
+       s.cluster.Login.OpenIDConnect.AuthenticationRequestParameters = map[string]string{"testkey": "testvalue"}
        return
 }
 
index 9dc9e17dd815b1818bc17bb20c074d69982e146d..2e39985c2a7cca989866d20eb250f1643873739e 100644 (file)
@@ -151,19 +151,21 @@ type Cluster struct {
                        UsernameAttribute  string
                }
                Google struct {
-                       Enable                  bool
-                       ClientID                string
-                       ClientSecret            string
-                       AlternateEmailAddresses bool
+                       Enable                          bool
+                       ClientID                        string
+                       ClientSecret                    string
+                       AlternateEmailAddresses         bool
+                       AuthenticationRequestParameters map[string]string
                }
                OpenIDConnect struct {
-                       Enable             bool
-                       Issuer             string
-                       ClientID           string
-                       ClientSecret       string
-                       EmailClaim         string
-                       EmailVerifiedClaim string
-                       UsernameClaim      string
+                       Enable                          bool
+                       Issuer                          string
+                       ClientID                        string
+                       ClientSecret                    string
+                       EmailClaim                      string
+                       EmailVerifiedClaim              string
+                       UsernameClaim                   string
+                       AuthenticationRequestParameters map[string]string
                }
                PAM struct {
                        Enable             bool