Skip to content

Commit 2b84717

Browse files
Nico Muerdtermonstermunchkin
Nico Muerdter
andcommitted
add alternativeIssuer to verifier
Co-authored-by: Thomas Hipp <[email protected]>
1 parent a66d6e2 commit 2b84717

File tree

3 files changed

+40
-19
lines changed

3 files changed

+40
-19
lines changed

oidc/oidc.go

+13-10
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ func doRequest(ctx context.Context, req *http.Request) (*http.Response, error) {
9797

9898
// Provider represents an OpenID Connect server's configuration.
9999
type Provider struct {
100-
issuer string
100+
issuer string
101+
alternativeIssuer []string
102+
101103
authURL string
102104
tokenURL string
103105
deviceAuthURL string
@@ -280,15 +282,16 @@ func NewProvider(ctx context.Context, issuer string, alternativeIssuer ...string
280282
}
281283
}
282284
return &Provider{
283-
issuer: issuerURL,
284-
authURL: p.AuthURL,
285-
tokenURL: p.TokenURL,
286-
deviceAuthURL: p.DeviceAuthURL,
287-
userInfoURL: p.UserInfoURL,
288-
jwksURL: p.JWKSURL,
289-
algorithms: algs,
290-
rawClaims: body,
291-
client: getClient(ctx),
285+
issuer: issuerURL,
286+
alternativeIssuer: alternativeIssuer,
287+
authURL: p.AuthURL,
288+
tokenURL: p.TokenURL,
289+
deviceAuthURL: p.DeviceAuthURL,
290+
userInfoURL: p.UserInfoURL,
291+
jwksURL: p.JWKSURL,
292+
algorithms: algs,
293+
rawClaims: body,
294+
client: getClient(ctx),
292295
}, nil
293296
}
294297

oidc/verify.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"io"
1111
"net/http"
12+
"slices"
1213
"strings"
1314
"time"
1415

@@ -50,9 +51,10 @@ type KeySet interface {
5051

5152
// IDTokenVerifier provides verification for ID Tokens.
5253
type IDTokenVerifier struct {
53-
keySet KeySet
54-
config *Config
55-
issuer string
54+
keySet KeySet
55+
config *Config
56+
issuer string
57+
alternativeIssuer []string
5658
}
5759

5860
// NewVerifier returns a verifier manually constructed from a key set and issuer URL.
@@ -71,8 +73,8 @@ type IDTokenVerifier struct {
7173
//
7274
// keySet := &oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{pub1, pub2}}
7375
// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config)
74-
func NewVerifier(issuerURL string, keySet KeySet, config *Config) *IDTokenVerifier {
75-
return &IDTokenVerifier{keySet: keySet, config: config, issuer: issuerURL}
76+
func NewVerifier(issuerURL string, keySet KeySet, config *Config, alternativeIssuer ...string) *IDTokenVerifier {
77+
return &IDTokenVerifier{keySet: keySet, config: config, issuer: issuerURL, alternativeIssuer: alternativeIssuer}
7678
}
7779

7880
// Config is the configuration for an IDTokenVerifier.
@@ -142,7 +144,7 @@ func (p *Provider) newVerifier(keySet KeySet, config *Config) *IDTokenVerifier {
142144
cp.SupportedSigningAlgs = p.algorithms
143145
config = cp
144146
}
145-
return NewVerifier(p.issuer, keySet, config)
147+
return NewVerifier(p.issuer, keySet, config, p.alternativeIssuer...)
146148
}
147149

148150
func parseJWT(p string) ([]byte, error) {
@@ -257,14 +259,16 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
257259
}
258260

259261
// Check issuer.
260-
if !v.config.SkipIssuerCheck && t.Issuer != v.issuer {
262+
v.alternativeIssuer = append(v.alternativeIssuer, v.issuer)
263+
264+
if !v.config.SkipIssuerCheck && !slices.Contains(v.alternativeIssuer, t.Issuer) {
261265
// Google sometimes returns "accounts.google.com" as the issuer claim instead of
262266
// the required "https://accounts.google.com". Detect this case and allow it only
263267
// for Google.
264268
//
265269
// We will not add hooks to let other providers go off spec like this.
266270
if !(v.issuer == issuerGoogleAccounts && t.Issuer == issuerGoogleAccountsNoScheme) {
267-
return nil, fmt.Errorf("oidc: id token issued by a different provider, expected %q got %q", v.issuer, t.Issuer)
271+
return nil, fmt.Errorf("oidc: id token issued by a different provider, expected one of %v got %q", v.alternativeIssuer, t.Issuer)
268272
}
269273
}
270274

oidc/verify_test.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ func TestVerify(t *testing.T) {
4646
signKey: newRSAKey(t),
4747
wantErr: true,
4848
},
49+
{
50+
name: "alternative issuer",
51+
issuer: "https://bar",
52+
alternativeIssuer: []string{"https://bar", "https://baz"},
53+
idToken: `{"iss":"https://foo"}`,
54+
config: Config{
55+
SkipClientIDCheck: true,
56+
SkipExpiryCheck: true,
57+
},
58+
signKey: newRSAKey(t),
59+
wantErr: true,
60+
},
4961
{
5062
name: "skip issuer check",
5163
issuer: "https://bar",
@@ -561,6 +573,8 @@ type verificationTest struct {
561573
// If not provided defaults to "https://foo"
562574
issuer string
563575

576+
alternativeIssuer []string
577+
564578
// JWT payload (just the claims).
565579
idToken string
566580

@@ -598,7 +612,7 @@ func (v verificationTest) runGetToken(t *testing.T) (*IDToken, error) {
598612
} else if v.signKey != nil {
599613
ks = &StaticKeySet{PublicKeys: []crypto.PublicKey{v.signKey.pub}}
600614
}
601-
verifier := NewVerifier(issuer, ks, &v.config)
615+
verifier := NewVerifier(issuer, ks, &v.config, v.alternativeIssuer...)
602616

603617
return verifier.Verify(ctx, token)
604618
}

0 commit comments

Comments
 (0)