Skip to content

Commit 21576ba

Browse files
committed
oidc ignore client/audience support
1 parent 13b1771 commit 21576ba

File tree

4 files changed

+119
-3
lines changed

4 files changed

+119
-3
lines changed

.chloggen/oidc-ignore-audience.yaml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: oidcauthextension
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add ignore_audience config option for ignoring oidc audience
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [36568]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: go-oidc SkipClientIDCheck is set based on config ignore_audience
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

extension/oidcauthextension/config.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ type Config struct {
1414

1515
// Audience of the token, used during the verification.
1616
// For example: "https://accounts.google.com" or "https://login.salesforce.com".
17-
// Required.
17+
// Required unless IgnoreAudience is true.
1818
Audience string `mapstructure:"audience"`
1919

20+
// When true, this skips validating the audience field.
21+
// Optional.
22+
IgnoreAudience bool `mapstructure:"ignore_audience"`
23+
2024
// The local path for the issuer CA's TLS server cert.
2125
// Optional.
2226
IssuerCAPath string `mapstructure:"issuer_ca_path"`
@@ -31,7 +35,7 @@ type Config struct {
3135
}
3236

3337
func (c *Config) Validate() error {
34-
if c.Audience == "" {
38+
if c.Audience == "" && !c.IgnoreAudience {
3539
return errNoAudienceProvided
3640
}
3741
if c.IssuerURL == "" {

extension/oidcauthextension/extension.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ func (e *oidcExtension) Start(ctx context.Context, _ component.Host) error {
6868
return fmt.Errorf("failed to get configuration from the auth server: %w", err)
6969
}
7070
e.verifier = e.provider.Verifier(&oidc.Config{
71-
ClientID: e.cfg.Audience,
71+
ClientID: e.cfg.Audience,
72+
SkipClientIDCheck: e.cfg.IgnoreAudience,
7273
})
7374
return nil
7475
}

extension/oidcauthextension/extension_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,76 @@ func TestOIDCAuthenticationSucceeded(t *testing.T) {
7979
// TODO(jpkroehling): assert that the authentication routine set the subject/membership to the resource
8080
}
8181

82+
func TestOIDCAuthenticationSucceededIgnoreAudienceMismatch(t *testing.T) {
83+
// prepare
84+
oidcServer, err := newOIDCServer()
85+
require.NoError(t, err)
86+
oidcServer.Start()
87+
defer oidcServer.Close()
88+
89+
config := &Config{
90+
IssuerURL: oidcServer.URL,
91+
Audience: "unit-test",
92+
IgnoreAudience: true,
93+
}
94+
p := newTestExtension(t, config)
95+
96+
err = p.Start(context.Background(), componenttest.NewNopHost())
97+
require.NoError(t, err)
98+
99+
payload, _ := json.Marshal(map[string]any{
100+
"iss": oidcServer.URL,
101+
"aud": "not-unit-test",
102+
"exp": time.Now().Add(time.Minute).Unix(),
103+
})
104+
token, err := oidcServer.token(payload)
105+
require.NoError(t, err)
106+
107+
srvAuth, ok := p.(extensionauth.Server)
108+
require.True(t, ok)
109+
110+
// test
111+
ctx, err := srvAuth.Authenticate(context.Background(), map[string][]string{"authorization": {fmt.Sprintf("Bearer %s", token)}})
112+
113+
// verify
114+
assert.NoError(t, err)
115+
assert.NotNil(t, ctx)
116+
}
117+
118+
func TestOIDCAuthenticationFailAudienceMismatch(t *testing.T) {
119+
// prepare
120+
oidcServer, err := newOIDCServer()
121+
require.NoError(t, err)
122+
oidcServer.Start()
123+
defer oidcServer.Close()
124+
125+
config := &Config{
126+
IssuerURL: oidcServer.URL,
127+
Audience: "unit-test",
128+
}
129+
p := newTestExtension(t, config)
130+
131+
err = p.Start(context.Background(), componenttest.NewNopHost())
132+
require.NoError(t, err)
133+
134+
payload, _ := json.Marshal(map[string]any{
135+
"iss": oidcServer.URL,
136+
"aud": "not-unit-test",
137+
"exp": time.Now().Add(time.Minute).Unix(),
138+
})
139+
token, err := oidcServer.token(payload)
140+
require.NoError(t, err)
141+
142+
srvAuth, ok := p.(extensionauth.Server)
143+
require.True(t, ok)
144+
145+
// test
146+
_, err = srvAuth.Authenticate(context.Background(), map[string][]string{"authorization": {fmt.Sprintf("Bearer %s", token)}})
147+
148+
// verify
149+
assert.Error(t, err)
150+
}
151+
82152
func TestOIDCProviderForConfigWithTLS(t *testing.T) {
83153
// prepare the CA cert for the TLS handler
84154
cert := x509.Certificate{
@@ -441,6 +511,20 @@ func TestMissingClient(t *testing.T) {
441511
assert.Equal(t, errNoAudienceProvided, err)
442512
}
443513

514+
func TestIgnoreMissingClient(t *testing.T) {
515+
// prepare
516+
config := &Config{
517+
IssuerURL: "http://example.com/",
518+
IgnoreAudience: true,
519+
}
520+
521+
// test
522+
err := config.Validate()
523+
524+
// verify
525+
assert.NoError(t, err)
526+
}
527+
444528
func TestMissingIssuerURL(t *testing.T) {
445529
// prepare
446530
config := &Config{

0 commit comments

Comments
 (0)