diff --git a/contrib/token-server/token.go b/contrib/token-server/token.go index a66c767de..dc0956d4a 100644 --- a/contrib/token-server/token.go +++ b/contrib/token-server/token.go @@ -180,7 +180,7 @@ func (issuer *TokenIssuer) CreateJWT(subject string, audience string, grantedAcc claimSet := token.ClaimSet{ Issuer: issuer.Issuer, Subject: subject, - Audience: audience, + Audience: []string{audience}, Expiration: now.Add(exp).Unix(), NotBefore: now.Unix(), IssuedAt: now.Unix(), diff --git a/registry/auth/token/token.go b/registry/auth/token/token.go index 2f86120a3..4c182d95b 100644 --- a/registry/auth/token/token.go +++ b/registry/auth/token/token.go @@ -42,13 +42,13 @@ type ResourceActions struct { // ClaimSet describes the main section of a JSON Web Token. type ClaimSet struct { // Public claims - Issuer string `json:"iss"` - Subject string `json:"sub"` - Audience string `json:"aud"` - Expiration int64 `json:"exp"` - NotBefore int64 `json:"nbf"` - IssuedAt int64 `json:"iat"` - JWTID string `json:"jti"` + Issuer string `json:"iss"` + Subject string `json:"sub"` + Audience WeakStringList `json:"aud"` + Expiration int64 `json:"exp"` + NotBefore int64 `json:"nbf"` + IssuedAt int64 `json:"iat"` + JWTID string `json:"jti"` // Private claims Access []*ResourceActions `json:"access"` @@ -141,8 +141,8 @@ func (t *Token) Verify(verifyOpts VerifyOptions) error { } // Verify that the Audience claim is allowed. - if !contains(verifyOpts.AcceptedAudiences, t.Claims.Audience) { - log.Infof("token intended for another audience: %q", t.Claims.Audience) + if !containsAny(verifyOpts.AcceptedAudiences, t.Claims.Audience) { + log.Infof("token intended for another audience: %v", t.Claims.Audience) return ErrInvalidToken } @@ -185,13 +185,15 @@ func (t *Token) Verify(verifyOpts VerifyOptions) error { // VerifySigningKey attempts to get the key which was used to sign this token. // The token header should contain either of these 3 fields: -// `x5c` - The x509 certificate chain for the signing key. Needs to be -// verified. -// `jwk` - The JSON Web Key representation of the signing key. -// May contain its own `x5c` field which needs to be verified. -// `kid` - The unique identifier for the key. This library interprets it -// as a libtrust fingerprint. The key itself can be looked up in -// the trustedKeys field of the given verify options. +// +// `x5c` - The x509 certificate chain for the signing key. Needs to be +// verified. +// `jwk` - The JSON Web Key representation of the signing key. +// May contain its own `x5c` field which needs to be verified. +// `kid` - The unique identifier for the key. This library interprets it +// as a libtrust fingerprint. The key itself can be looked up in +// the trustedKeys field of the given verify options. +// // Each of these methods are tried in that order of preference until the // signing key is found or an error is returned. func (t *Token) VerifySigningKey(verifyOpts VerifyOptions) (signingKey libtrust.PublicKey, err error) { diff --git a/registry/auth/token/token_test.go b/registry/auth/token/token_test.go index 77250d4bd..0bdcd3639 100644 --- a/registry/auth/token/token_test.go +++ b/registry/auth/token/token_test.go @@ -117,7 +117,7 @@ func makeTestToken(issuer, audience string, access []*ResourceActions, rootKey l claimSet := &ClaimSet{ Issuer: issuer, Subject: "foo", - Audience: audience, + Audience: []string{audience}, Expiration: exp.Unix(), NotBefore: now.Unix(), IssuedAt: now.Unix(), @@ -307,10 +307,10 @@ func writeTempRootCerts(rootKeys []libtrust.PrivateKey) (filename string, err er // TestAccessController tests complete integration of the token auth package. // It starts by mocking the options for a token auth accessController which // it creates. It then tries a few mock requests: -// - don't supply a token; should error with challenge -// - supply an invalid token; should error with challenge -// - supply a token with insufficient access; should error with challenge -// - supply a valid token; should not error +// - don't supply a token; should error with challenge +// - supply an invalid token; should error with challenge +// - supply a token with insufficient access; should error with challenge +// - supply a valid token; should not error func TestAccessController(t *testing.T) { // Make 2 keys; only the first is to be a trusted root key. rootKeys, err := makeRootKeys(2) diff --git a/registry/auth/token/util.go b/registry/auth/token/util.go index d7f95be42..a219df862 100644 --- a/registry/auth/token/util.go +++ b/registry/auth/token/util.go @@ -56,3 +56,14 @@ func contains(ss []string, q string) bool { return false } + +// containsAny returns true if any of q is found in ss. +func containsAny(ss []string, q []string) bool { + for _, s := range ss { + if contains(q, s) { + return true + } + } + + return false +}