diff --git a/extension/oidcauthextension/config.go b/extension/oidcauthextension/config.go index 327baea5365f..5df328e4f51d 100644 --- a/extension/oidcauthextension/config.go +++ b/extension/oidcauthextension/config.go @@ -15,9 +15,13 @@ type Config struct { // Audience of the token, used during the verification. // For example: "https://accounts.google.com" or "https://login.salesforce.com". - // Required. + // Required unless IgnoreAudience is true. Audience string `mapstructure:"audience"` + // When true, this skips validating the audience field. + // Optional. + IgnoreAudience bool `mapstructure:"ignore_audience"` + // The local path for the issuer CA's TLS server cert. // Optional. IssuerCAPath string `mapstructure:"issuer_ca_path"` @@ -32,7 +36,7 @@ type Config struct { } func (c *Config) Validate() error { - if c.Audience == "" { + if c.Audience == "" && !c.IgnoreAudience { return errNoAudienceProvided } if c.IssuerURL == "" { diff --git a/extension/oidcauthextension/extension.go b/extension/oidcauthextension/extension.go index c79e3231ef3a..db6c8b1ba3f1 100644 --- a/extension/oidcauthextension/extension.go +++ b/extension/oidcauthextension/extension.go @@ -68,6 +68,7 @@ func (e *oidcExtension) start(ctx context.Context, _ component.Host) error { } e.verifier = e.provider.Verifier(&oidc.Config{ ClientID: e.cfg.Audience, + SkipClientIDCheck: e.cfg.IgnoreAudience, }) return nil } diff --git a/extension/oidcauthextension/extension_test.go b/extension/oidcauthextension/extension_test.go index 92b72d15fa14..7ba868ed7b79 100644 --- a/extension/oidcauthextension/extension_test.go +++ b/extension/oidcauthextension/extension_test.go @@ -69,6 +69,52 @@ func TestOIDCAuthenticationSucceeded(t *testing.T) { // TODO(jpkroehling): assert that the authentication routine set the subject/membership to the resource } +func TestOIDCAuthenticationSucceededIgnoreAudience(t *testing.T) { + // prepare + oidcServer, err := newOIDCServer() + require.NoError(t, err) + oidcServer.Start() + defer oidcServer.Close() + + config := &Config{ + IssuerURL: oidcServer.URL, + Audience: "unit-test", + IgnoreAudience: true, + GroupsClaim: "memberships", + } + p := newExtension(config, zap.NewNop()) + + err = p.Start(context.Background(), componenttest.NewNopHost()) + require.NoError(t, err) + + payload, _ := json.Marshal(map[string]any{ + "sub": "jdoe@example.com", + "name": "jdoe", + "iss": oidcServer.URL, + "aud": "not-unit-test", + "exp": time.Now().Add(time.Minute).Unix(), + "memberships": []string{"department-1", "department-2"}, + }) + token, err := oidcServer.token(payload) + require.NoError(t, err) + + // test + ctx, err := p.Authenticate(context.Background(), map[string][]string{"authorization": {fmt.Sprintf("Bearer %s", token)}}) + + // verify + assert.NoError(t, err) + assert.NotNil(t, ctx) + + // test, upper-case header + ctx, err = p.Authenticate(context.Background(), map[string][]string{"Authorization": {fmt.Sprintf("Bearer %s", token)}}) + + // verify + assert.NoError(t, err) + assert.NotNil(t, ctx) + + // TODO(jpkroehling): assert that the authentication routine set the subject/membership to the resource +} + func TestOIDCProviderForConfigWithTLS(t *testing.T) { // prepare the CA cert for the TLS handler cert := x509.Certificate{ @@ -423,6 +469,20 @@ func TestMissingClient(t *testing.T) { assert.Equal(t, errNoAudienceProvided, err) } +func TestIgnoreMissingClient(t *testing.T) { + // prepare + config := &Config{ + IssuerURL: "http://example.com/", + IgnoreAudience: true, + } + + // test + err := config.Validate() + + // verify + assert.Nil(t, err) +} + func TestMissingIssuerURL(t *testing.T) { // prepare config := &Config{