mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
auth: add new optional OIDCDisableUserInfo setting for OIDC auth provider (#19566)
Add new optional `OIDCDisableUserInfo` setting for OIDC auth provider which disables a request to the identity provider to get OIDC UserInfo. This option is helpful when your identity provider doesn't send any additional claims from the UserInfo endpoint, such as Microsoft AD FS OIDC Provider: > The AD FS UserInfo endpoint always returns the subject claim as specified in the > OpenID standards. AD FS doesn't support additional claims requested via the > UserInfo endpoint Fixes #19318
This commit is contained in:
3
.changelog/19566.txt
Normal file
3
.changelog/19566.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
auth: Added new optional OIDCDisableUserInfo setting for OIDC auth provider
|
||||
```
|
||||
@@ -826,6 +826,8 @@ type ACLAuthMethodConfig struct {
|
||||
OIDCClientID string
|
||||
// The OAuth Client Secret configured with the OIDC provider
|
||||
OIDCClientSecret string
|
||||
// Disable claims from the OIDC UserInfo endpoint
|
||||
OIDCDisableUserInfo bool
|
||||
// List of OIDC scopes
|
||||
OIDCScopes []string
|
||||
// List of auth claims that are valid for login
|
||||
|
||||
@@ -93,6 +93,7 @@ func formatAuthMethodConfig(config *api.ACLAuthMethodConfig) string {
|
||||
fmt.Sprintf("OIDC Discovery URL|%s", config.OIDCDiscoveryURL),
|
||||
fmt.Sprintf("OIDC Client ID|%s", config.OIDCClientID),
|
||||
fmt.Sprintf("OIDC Client Secret|%s", config.OIDCClientSecret),
|
||||
fmt.Sprintf("OIDC Disable UserInfo|%t", config.OIDCDisableUserInfo),
|
||||
fmt.Sprintf("OIDC Scopes|%s", strings.Join(config.OIDCScopes, ",")),
|
||||
fmt.Sprintf("Bound audiences|%s", strings.Join(config.BoundAudiences, ",")),
|
||||
fmt.Sprintf("Bound issuer|%s", strings.Join(config.BoundIssuer, ",")),
|
||||
|
||||
@@ -37,6 +37,7 @@ func TestACLOIDC_GetAuthURL(t *testing.T) {
|
||||
OIDCDiscoveryURL: oidcTestProvider.Addr(),
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "verysecretsecret",
|
||||
OIDCDisableUserInfo: false,
|
||||
BoundAudiences: []string{"mock"},
|
||||
AllowedRedirectURIs: []string{"http://127.0.0.1:4649/oidc/callback"},
|
||||
DiscoveryCaPem: []string{oidcTestProvider.CACert()},
|
||||
@@ -96,6 +97,7 @@ func TestACLOIDC_CompleteAuth(t *testing.T) {
|
||||
OIDCDiscoveryURL: oidcTestProvider.Addr(),
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "verysecretsecret",
|
||||
OIDCDisableUserInfo: false,
|
||||
BoundAudiences: []string{"mock"},
|
||||
AllowedRedirectURIs: []string{"http://127.0.0.1:4649/oidc/callback"},
|
||||
DiscoveryCaPem: []string{oidcTestProvider.CACert()},
|
||||
|
||||
@@ -35,6 +35,7 @@ func TestProviderCache(t *testing.T) {
|
||||
OIDCDiscoveryURL: oidcTestProvider.Addr(),
|
||||
OIDCClientID: "alice",
|
||||
OIDCClientSecret: "ssshhhh",
|
||||
OIDCDisableUserInfo: false,
|
||||
AllowedRedirectURIs: []string{"http://example.com"},
|
||||
DiscoveryCaPem: []string{oidcTestProvider.CACert()},
|
||||
SigningAlgs: []string{string(tpAlg)},
|
||||
|
||||
@@ -2747,9 +2747,11 @@ func (a *ACL) OIDCCompleteAuth(
|
||||
}
|
||||
|
||||
var userClaims map[string]interface{}
|
||||
if userTokenSource := oidcToken.StaticTokenSource(); userTokenSource != nil {
|
||||
if err := oidcProvider.UserInfo(ctx, userTokenSource, idTokenClaims["sub"].(string), &userClaims); err != nil {
|
||||
return fmt.Errorf("failed to retrieve the user info claims: %v", err)
|
||||
if !authMethod.Config.OIDCDisableUserInfo {
|
||||
if userTokenSource := oidcToken.StaticTokenSource(); userTokenSource != nil {
|
||||
if err := oidcProvider.UserInfo(ctx, userTokenSource, idTokenClaims["sub"].(string), &userClaims); err != nil {
|
||||
return fmt.Errorf("failed to retrieve the user info claims: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -275,6 +275,7 @@ func ACLOIDCAuthMethod() *structs.ACLAuthMethod {
|
||||
OIDCDiscoveryURL: "http://example.com",
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "very secret secret",
|
||||
OIDCDisableUserInfo: false,
|
||||
OIDCScopes: []string{"groups"},
|
||||
BoundAudiences: []string{"sales", "engineering"},
|
||||
AllowedRedirectURIs: []string{"foo", "bar"},
|
||||
|
||||
@@ -784,6 +784,7 @@ func (a *ACLAuthMethod) SetHash() []byte {
|
||||
_, _ = hash.Write([]byte(a.Config.OIDCDiscoveryURL))
|
||||
_, _ = hash.Write([]byte(a.Config.OIDCClientID))
|
||||
_, _ = hash.Write([]byte(a.Config.OIDCClientSecret))
|
||||
_, _ = hash.Write([]byte(strconv.FormatBool(a.Config.OIDCDisableUserInfo)))
|
||||
_, _ = hash.Write([]byte(a.Config.ExpirationLeeway.String()))
|
||||
_, _ = hash.Write([]byte(a.Config.NotBeforeLeeway.String()))
|
||||
_, _ = hash.Write([]byte(a.Config.ClockSkewLeeway.String()))
|
||||
@@ -990,6 +991,9 @@ type ACLAuthMethodConfig struct {
|
||||
// The OAuth Client Secret configured with the OIDC provider
|
||||
OIDCClientSecret string
|
||||
|
||||
// Disable claims from the OIDC UserInfo endpoint
|
||||
OIDCDisableUserInfo bool
|
||||
|
||||
// List of OIDC scopes
|
||||
OIDCScopes []string
|
||||
|
||||
|
||||
@@ -1098,6 +1098,7 @@ func TestACLAuthMethod_Stub(t *testing.T) {
|
||||
OIDCDiscoveryURL: "http://example.com",
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "very secret secret",
|
||||
OIDCDisableUserInfo: false,
|
||||
BoundAudiences: []string{"audience1", "audience2"},
|
||||
AllowedRedirectURIs: []string{"foo", "bar"},
|
||||
DiscoveryCaPem: []string{"foo"},
|
||||
@@ -1138,6 +1139,7 @@ func TestACLAuthMethod_Equal(t *testing.T) {
|
||||
OIDCDiscoveryURL: "http://example.com",
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "very secret secret",
|
||||
OIDCDisableUserInfo: false,
|
||||
BoundAudiences: []string{"audience1", "audience2"},
|
||||
AllowedRedirectURIs: []string{"foo", "bar"},
|
||||
DiscoveryCaPem: []string{"foo"},
|
||||
@@ -1190,6 +1192,7 @@ func TestACLAuthMethod_Copy(t *testing.T) {
|
||||
OIDCDiscoveryURL: "http://example.com",
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "very secret secret",
|
||||
OIDCDisableUserInfo: false,
|
||||
BoundAudiences: []string{"audience1", "audience2"},
|
||||
AllowedRedirectURIs: []string{"foo", "bar"},
|
||||
DiscoveryCaPem: []string{"foo"},
|
||||
@@ -1282,6 +1285,7 @@ func TestACLAuthMethod_Merge(t *testing.T) {
|
||||
OIDCDiscoveryURL: "http://example.com",
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "very secret secret",
|
||||
OIDCDisableUserInfo: false,
|
||||
BoundAudiences: []string{"audience1", "audience2"},
|
||||
AllowedRedirectURIs: []string{"foo", "bar"},
|
||||
DiscoveryCaPem: []string{"foo"},
|
||||
@@ -1309,6 +1313,7 @@ func TestACLAuthMethodConfig_Copy(t *testing.T) {
|
||||
OIDCDiscoveryURL: "http://example.com",
|
||||
OIDCClientID: "mock",
|
||||
OIDCClientSecret: "very secret secret",
|
||||
OIDCDisableUserInfo: false,
|
||||
OIDCScopes: []string{"groups"},
|
||||
BoundAudiences: []string{"audience1", "audience2"},
|
||||
AllowedRedirectURIs: []string{"foo", "bar"},
|
||||
|
||||
@@ -63,6 +63,11 @@ The table below shows this endpoint's support for
|
||||
- `OIDCClientSecret` `(string: <required>)` - The OAuth client secret
|
||||
configured with your OIDC provider.
|
||||
|
||||
- `OIDCDisableUserInfo` `(bool: false)` - When set to `true`, Nomad will not make
|
||||
a request to the identity provider to get OIDC UserInfo. You may wish to set this
|
||||
if your identity provider doesn't send any additional claims from the UserInfo
|
||||
endpoint.
|
||||
|
||||
- `OIDCScopes` `(array<string>)` - List of OIDC scopes.
|
||||
|
||||
- `BoundAudiences` `(array<string>)` - List of aud claims that are valid for
|
||||
@@ -228,6 +233,11 @@ queries](/nomad/api-docs#blocking-queries) and [required ACLs](/nomad/api-docs#a
|
||||
- `OIDCClientSecret` `(string: "")` - The OAuth client secret
|
||||
configured with your OIDC provider.
|
||||
|
||||
- `OIDCDisableUserInfo` `(bool: false)` - When set to `true`, Nomad will not make
|
||||
a request to the identity provider to get OIDC UserInfo. You may wish to set this
|
||||
if your identity provider doesn't send any additional claims from the UserInfo
|
||||
endpoint.
|
||||
|
||||
- `OIDCScopes` `(array<string>)` - List of OIDC scopes.
|
||||
|
||||
- `BoundAudiences` `(array<string>)` - List of aud claims that are valid for
|
||||
|
||||
Reference in New Issue
Block a user