-
Notifications
You must be signed in to change notification settings - Fork 1.9k
OIDC Authentication Driver #14406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
OIDC Authentication Driver #14406
Changes from 16 commits
Commits
Show all changes
99 commits
Select commit
Hold shift + click to select a range
b9c5d08
Initial commit of OIDC auth driver module, implementation of Authenti…
CL-Andrew 1e4d118
fix: build errors
harry-anderson 04eb2a7
feat: fix build errors
harry-anderson c15e09a
chore: go tidy
harry-anderson 8de14c0
feat: impl WebServerOIDC methods
harry-anderson d280b18
feat: get OIDC webserver redirect working
harry-anderson 17e5899
fix: insert user session
harry-anderson 77dd003
feat: add todos
harry-anderson 4712386
feat: try extend router
harry-anderson 2399c18
feat: refactor OIDC handlers to use gin
harry-anderson e47756b
feat: set cookie working
harry-anderson ce4bdea
revert: revert debug changes
harry-anderson 03cafb4
feat: add random state
harry-anderson ccbf892
fix: CodeQL issues
harry-anderson 39b880e
Merge branch 'develop' into oidc-support
harry-anderson 67a8b38
chore: fix merge conflicts and go tidy
harry-anderson e284a24
feat: get oidc flow working with the frontend
harry-anderson e184ce0
feat: oidc-exchange and oidc-enabled endpoints
harry-anderson 3d24842
feat: cleanup, check stored state, remove unused
harry-anderson 5c477cd
cleanup: remove HTTPPort from OIDC config
harry-anderson e418e0d
feat: config changes
harry-anderson 5de7cbb
feat: update config names
harry-anderson 767e2fa
feat: update config names
harry-anderson e5549a8
fix: delete session bug
harry-anderson afc241d
feat: fix sonarkube issues
harry-anderson 253ca3d
feat: update mocks and go.mod
harry-anderson 1e60501
feat: add changeset
harry-anderson ab371be
feat: rename claimKey to claimName
harry-anderson 5eb4939
chore: make tidy
harry-anderson c0bf129
chore: make rm-mocked
harry-anderson b5d43f4
fix docs test
harry-anderson 0310974
chore: fix ci lint issues
harry-anderson 04ea82a
try fix authentication.go
harry-anderson e78affd
fix: lint
harry-anderson 22aa0a8
chore: fix sonar qube issues
harry-anderson 12adc63
fix: lint issue
harry-anderson bc14996
feat: add missing oidc config blocks in testdata files
harry-anderson 9876d5a
chore: add missing files
harry-anderson 5438a3a
chore: update test files with oidc config blocks
harry-anderson 562f451
chore: consistent example client_id
harry-anderson ccce240
fix: capital C ClientSecret in testdata
harry-anderson 659f89d
feat: add oidc default to valid.txtar and invalid.txtar
harry-anderson 6c30ddd
feat: add OIDC blocks for txtar files
harry-anderson bca75dd
fix merge confiict
harry-anderson e5acecc
feat: fix migration number conflict
harry-anderson d27f233
feat: add oidc to config_test.go
harry-anderson e62e8aa
fix: double quotes where should use single quotes
harry-anderson 0ce307b
feat: groups single quotes
harry-anderson 3167db9
chore: go mod tidy
harry-anderson 1ee6139
chore: single quotes everywhere
harry-anderson 51a1c89
chore: go mod
harry-anderson bb38a04
chore: go sum
harry-anderson ca3eff0
fix double quote error
harry-anderson 6b063b7
fix double quotes
harry-anderson e3b57ab
feat: run make config-docs
harry-anderson 3d206c9
chore: manual go.sum changes
harry-anderson 62088ba
chore: try force captial C
harry-anderson fb80c88
chore: remove trailing whitespace and use secret string type
harry-anderson 2d9a3ef
feat: manual go.mod changes
harry-anderson 3ddd535
chore: go mod
harry-anderson 0855048
Merge branch 'develop' into oidc-support
harry-anderson ee5faf9
chore: cast to string
harry-anderson e5a1b4a
chore: remove whitespace
harry-anderson 1beb7f2
fix: UserApi casing
harry-anderson feb17d1
fix: add missing required field ClientID
harry-anderson 0a17fa0
chore: go mod tidy
harry-anderson 7cb34f8
fix: add changeset
harry-anderson 8b0db08
chore: remove duplicate change set
harry-anderson 8b707f2
fix: remove duplicate changeset
harry-anderson 99b50ca
fix: remove old changeset not found and add new changeset
harry-anderson 195cef2
feat: add back missing changeset
harry-anderson 0210066
try: remove tags from changeset open-lizards-switch.md
harry-anderson 14a2b16
feat: added changeset tags
harry-anderson 2046b0f
rmove tags
harry-anderson 008c49a
chore: add tags to change set
harry-anderson f181184
feat: add ValidateConfig logic
harry-anderson 23ffcf8
chore: add validate config functions
harry-anderson 49c68d4
chore: uncomment validate config for web secrets
harry-anderson 1316a4d
feat: impl ValidateConfig for WebServerSecrets
harry-anderson b184143
test: stup test
harry-anderson fab4af0
feat: mock provider
harry-anderson f61c30a
test: OIDC findUser test
harry-anderson 6741909
test: add more unit tests for OIDC
harry-anderson d2b7a13
test: createSession test and bugfix
harry-anderson 7968bcc
test: more unit tests
harry-anderson da12dd6
test: more unit tests for oidc
harry-anderson 345d4e0
test: more oidc tests
harry-anderson 67f1cc6
chore: bump migration number
harry-anderson f7e5ac1
chore: revert changes to LDAP config field UserApiTokenEnabled
harry-anderson 4d0038f
fix: lint issues
harry-anderson a3a866c
chore: fix lint issues
harry-anderson 8b95c19
chore: fix lint issues
harry-anderson 687eca6
fix: fix lint issues
harry-anderson 288631a
fix: casing
harry-anderson c41c5b7
chore: remove todo
harry-anderson 3597883
Bump operator-ui version and update web assets
CL-Andrew dffcef0
error logging fixes and simplify db calls
CL-Andrew 78728da
error message casing fix
CL-Andrew 4bf0051
simplify db transaction calls
CL-Andrew File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,11 @@ BackupURL = "postgresql://user:[email protected]:5432/dbname?sslmode | |
| # Environment variable: `CL_DATABASE_ALLOW_SIMPLE_PASSWORDS` | ||
| AllowSimplePasswords = false # Default | ||
|
|
||
| # Optional OIDC config | ||
| [WebServer.OIDC] | ||
| # Auth client application secret | ||
| clientSecret = "secret" # Example | ||
|
|
||
| # Optional LDAP config | ||
| [WebServer.LDAP] | ||
| # ServerAddress is the full ldaps:// address of the ldap server to authenticate with and query | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -749,6 +749,7 @@ | |
| ListenIP *net.IP | ||
|
|
||
| LDAP WebServerLDAP `toml:",omitempty"` | ||
| OIDC WebServerOIDC `toml:",omitempty"` | ||
| MFA WebServerMFA `toml:",omitempty"` | ||
| RateLimit WebServerRateLimit `toml:",omitempty"` | ||
| TLS WebServerTLS `toml:",omitempty"` | ||
|
|
@@ -793,43 +794,86 @@ | |
| } | ||
|
|
||
| w.LDAP.setFrom(&f.LDAP) | ||
| w.OIDC.setFrom(&f.OIDC) | ||
| w.MFA.setFrom(&f.MFA) | ||
| w.RateLimit.setFrom(&f.RateLimit) | ||
| w.TLS.setFrom(&f.TLS) | ||
| } | ||
|
|
||
| func (w *WebServer) ValidateConfig() (err error) { | ||
| // Validate LDAP fields when authentication method is LDAPAuth | ||
| if *w.AuthenticationMethod != string(sessions.LDAPAuth) { | ||
| return | ||
| switch *w.AuthenticationMethod { | ||
| case string(sessions.LDAPAuth): | ||
| // Assert LDAP fields when AuthMethod set to LDAP | ||
| if *w.LDAP.BaseDN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.BaseDN", Msg: "LDAP BaseDN can not be empty"}) | ||
| } | ||
| if *w.LDAP.BaseUserAttr == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.BaseUserAttr", Msg: "LDAP BaseUserAttr can not be empty"}) | ||
| } | ||
| if *w.LDAP.UsersDN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.UsersDN", Msg: "LDAP UsersDN can not be empty"}) | ||
| } | ||
| if *w.LDAP.GroupsDN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.GroupsDN", Msg: "LDAP GroupsDN can not be empty"}) | ||
| } | ||
| if *w.LDAP.AdminUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.AdminUserGroupCN", Msg: "LDAP AdminUserGroupCN can not be empty"}) | ||
| } | ||
| if *w.LDAP.EditUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) | ||
| } | ||
| if *w.LDAP.RunUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP RunUserGroupCN can not be empty"}) | ||
| } | ||
| if *w.LDAP.ReadUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.ReadUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) | ||
| } | ||
| return err | ||
| case string(sessions.OIDCAuth): | ||
| fmt.Println("%#v", w.OIDC) | ||
| if *w.OIDC.ClientID == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.ClientID", Msg: "OIDC ClientID can not be empty"}) | ||
| } | ||
| if *w.OIDC.ProviderDomain == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.ProviderDomain", Msg: "OIDC ProviderDomain can not be empty"}) | ||
| } | ||
| if *w.OIDC.OAuth2ProviderRouteSuffix == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.OAuth2ProviderRouteSuffix", Msg: "OIDC OAuth2ProviderRouteSuffix can not be empty"}) | ||
| } | ||
| if *w.OIDC.OIDCCallbackURL == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.OIDCCallbackURL", Msg: "OIDC OIDCCallbackURL can not be empty"}) | ||
| } | ||
| if *w.OIDC.OIDCCallbackURLSuffix == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.OIDCCallbackURLSuffix", Msg: "OIDC OIDCCallbackURLSuffix can not be empty"}) | ||
| } | ||
| if w.OIDC.HTTPPort == 0 { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.HTTPPort", Msg: "OIDC HTTPPort can not be empty"}) | ||
| } | ||
| if *w.OIDC.AdminUserGroupClaim == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.AdminUserGroupClaim", Msg: "OIDC AdminUserGroupClaim can not be empty"}) | ||
| } | ||
| if *w.OIDC.EditUserGroupClaim == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.EditUserGroupClaim", Msg: "OIDC EditUserGroupClaim can not be empty"}) | ||
| } | ||
| if *w.OIDC.RunUserGroupClaim == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.RunUserGroupClaim", Msg: "OIDC RunUserGroupClaim can not be empty"}) | ||
| } | ||
| if *w.OIDC.ReadUserGroupClaim == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.ReadUserGroupClaim", Msg: "OIDC ReadUserGroupClaim can not be empty"}) | ||
| } | ||
| if w.OIDC.SessionTimeout == commonconfig.MustNewDuration(0) { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.SessionTimeout", Msg: "OIDC SessionTimeout can not be empty"}) | ||
| } | ||
| if w.OIDC.UserApiTokenEnabled == nil { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.UserApiTokenEnabled", Msg: "OIDC UserApiTokenEnabled can not be empty"}) | ||
| } | ||
| if w.OIDC.UserAPITokenDuration == commonconfig.MustNewDuration(0) { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "OIDC.UserAPITokenDuration", Msg: "OIDC UserAPITokenDuration can not be empty"}) | ||
| } | ||
| return err | ||
| } | ||
|
|
||
| // Assert LDAP fields when AuthMethod set to LDAP | ||
| if *w.LDAP.BaseDN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.BaseDN", Msg: "LDAP BaseDN can not be empty"}) | ||
| } | ||
| if *w.LDAP.BaseUserAttr == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.BaseUserAttr", Msg: "LDAP BaseUserAttr can not be empty"}) | ||
| } | ||
| if *w.LDAP.UsersDN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.UsersDN", Msg: "LDAP UsersDN can not be empty"}) | ||
| } | ||
| if *w.LDAP.GroupsDN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.GroupsDN", Msg: "LDAP GroupsDN can not be empty"}) | ||
| } | ||
| if *w.LDAP.AdminUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.AdminUserGroupCN", Msg: "LDAP AdminUserGroupCN can not be empty"}) | ||
| } | ||
| if *w.LDAP.EditUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) | ||
| } | ||
| if *w.LDAP.RunUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP RunUserGroupCN can not be empty"}) | ||
| } | ||
| if *w.LDAP.ReadUserGroupCN == "" { | ||
| err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.ReadUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) | ||
| } | ||
| return err | ||
| return nil | ||
harry-anderson marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| type WebServerMFA struct { | ||
|
|
@@ -993,15 +1037,87 @@ | |
| } | ||
| } | ||
|
|
||
| type WebServerOIDC struct { | ||
| ClientID *string | ||
| ProviderDomain *string | ||
| OAuth2ProviderRouteSuffix *string | ||
| OIDCCallbackURL *string | ||
| OIDCCallbackURLSuffix *string | ||
| HTTPPort uint16 | ||
| AdminUserGroupClaim *string | ||
| EditUserGroupClaim *string | ||
| RunUserGroupClaim *string | ||
| ReadUserGroupClaim *string | ||
| SessionTimeout *commonconfig.Duration | ||
| UserApiTokenEnabled *bool | ||
| UserAPITokenDuration *commonconfig.Duration | ||
| } | ||
|
|
||
| func (w *WebServerOIDC) setFrom(f *WebServerOIDC) { | ||
| if v := f.ClientID; v != nil { | ||
| w.ClientID = v | ||
| } | ||
| if v := f.ProviderDomain; v != nil { | ||
| w.ProviderDomain = v | ||
| } | ||
| if v := f.OAuth2ProviderRouteSuffix; v != nil { | ||
| w.OAuth2ProviderRouteSuffix = v | ||
| } | ||
| if v := f.OIDCCallbackURL; v != nil { | ||
| w.OIDCCallbackURL = v | ||
| } | ||
| if v := f.OIDCCallbackURLSuffix; v != nil { | ||
| w.OIDCCallbackURLSuffix = v | ||
| } | ||
| if v := f.HTTPPort; v != 0 { | ||
| w.HTTPPort = v | ||
| } | ||
| if v := f.AdminUserGroupClaim; v != nil { | ||
| w.AdminUserGroupClaim = v | ||
| } | ||
| if v := f.EditUserGroupClaim; v != nil { | ||
| w.EditUserGroupClaim = v | ||
| } | ||
| if v := f.RunUserGroupClaim; v != nil { | ||
| w.RunUserGroupClaim = v | ||
| } | ||
| if v := f.ReadUserGroupClaim; v != nil { | ||
| w.ReadUserGroupClaim = v | ||
| } | ||
| if v := f.SessionTimeout; v != nil { | ||
| w.SessionTimeout = v | ||
| } | ||
| if v := f.UserApiTokenEnabled; v != nil { | ||
| w.UserApiTokenEnabled = v | ||
| } | ||
| if v := f.UserAPITokenDuration; v != nil { | ||
| w.UserAPITokenDuration = v | ||
| } | ||
| } | ||
|
|
||
| type WebServerOIDCSecrets struct { | ||
| ClientSecret *string | ||
| } | ||
|
|
||
| func (w *WebServerOIDCSecrets) setFrom(f *WebServerOIDCSecrets) { | ||
| if v := f.ClientSecret; v != nil { | ||
| w.ClientSecret = v | ||
| } | ||
| } | ||
|
|
||
| type WebServerSecrets struct { | ||
| LDAP WebServerLDAPSecrets `toml:",omitempty"` | ||
| OIDC WebServerOIDCSecrets `toml:",omitempty"` | ||
| } | ||
|
|
||
| func (w *WebServerSecrets) SetFrom(f *WebServerSecrets) error { | ||
| w.LDAP.setFrom(&f.LDAP) | ||
| w.OIDC.setFrom(&f.OIDC) | ||
| return nil | ||
| } | ||
|
|
||
| // TODO: harry: add Validate function for WebServerSecrets and LDAPSecrets | ||
|
||
|
|
||
| type JobPipeline struct { | ||
| ExternalInitiatorsEnabled *bool | ||
| MaxRunDuration *commonconfig.Duration | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.