Skip to content

Commit 06ca5fb

Browse files
Nico Muerdtermonstermunchkin
Nico Muerdter
authored andcommitted
add alternativeIssuer to verifier
1 parent 846bde7 commit 06ca5fb

File tree

3 files changed

+38
-20
lines changed

3 files changed

+38
-20
lines changed

oidc/oidc.go

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

9797
// Provider represents an OpenID Connect server's configuration.
9898
type Provider struct {
99-
issuer string
99+
issuer string
100+
alternativeIssuer []string
101+
100102
authURL string
101103
tokenURL string
102104
deviceAuthURL string
@@ -164,7 +166,7 @@ var supportedAlgorithms = map[string]bool{
164166
// parsing.
165167
//
166168
// // Directly fetch the metadata document.
167-
// resp, err := http.Get("https://login.example.com/custom-metadata-path")
169+
// resp, err := http.Get("https://login.example.com/custom-metadata-path")
168170
// if err != nil {
169171
// // ...
170172
// }
@@ -280,15 +282,15 @@ 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: p.Issuer,
286+
alternativeIssuer: alternativeIssuer,
287+
authURL: p.AuthURL,
288+
tokenURL: p.TokenURL,
289+
userInfoURL: p.UserInfoURL,
290+
algorithms: algs,
291+
rawClaims: body,
292+
remoteKeySet: NewRemoteKeySet(ctx, p.JWKSURL),
293+
client: getClient(ctx),
292294
}, nil
293295
}
294296

oidc/verify.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ type KeySet interface {
5050

5151
// IDTokenVerifier provides verification for ID Tokens.
5252
type IDTokenVerifier struct {
53-
keySet KeySet
54-
config *Config
55-
issuer string
53+
keySet KeySet
54+
config *Config
55+
issuer string
56+
alternativeIssuer []string
5657
}
5758

5859
// NewVerifier returns a verifier manually constructed from a key set and issuer URL.
@@ -71,8 +72,8 @@ type IDTokenVerifier struct {
7172
//
7273
// keySet := &oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{pub1, pub2}}
7374
// 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}
75+
func NewVerifier(issuerURL string, keySet KeySet, config *Config, alternativeIssuer ...string) *IDTokenVerifier {
76+
return &IDTokenVerifier{keySet: keySet, config: config, issuer: issuerURL, alternativeIssuer: alternativeIssuer}
7677
}
7778

7879
// Config is the configuration for an IDTokenVerifier.
@@ -142,7 +143,7 @@ func (p *Provider) newVerifier(keySet KeySet, config *Config) *IDTokenVerifier {
142143
cp.SupportedSigningAlgs = p.algorithms
143144
config = cp
144145
}
145-
return NewVerifier(p.issuer, keySet, config)
146+
return NewVerifier(p.issuer, p.remoteKeySet, config, p.alternativeIssuer...)
146147
}
147148

148149
func parseJWT(p string) ([]byte, error) {
@@ -257,14 +258,15 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
257258
}
258259

259260
// Check issuer.
260-
if !v.config.SkipIssuerCheck && t.Issuer != v.issuer {
261+
issuerStr := strings.Join(append(v.alternativeIssuer, v.issuer), " ")
262+
if !v.config.SkipIssuerCheck && !strings.Contains(issuerStr, t.Issuer) {
261263
// Google sometimes returns "accounts.google.com" as the issuer claim instead of
262264
// the required "https://accounts.google.com". Detect this case and allow it only
263265
// for Google.
264266
//
265267
// We will not add hooks to let other providers go off spec like this.
266268
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)
269+
return nil, fmt.Errorf("oidc: id token issued by a different provider, expected one of %q got %q", issuerStr, t.Issuer)
268270
}
269271
}
270272

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)