diff --git a/claims.go b/claims.go index f0228f02..af78092f 100644 --- a/claims.go +++ b/claims.go @@ -16,13 +16,13 @@ type Claims interface { // https://tools.ietf.org/html/rfc7519#section-4.1 // See examples for how to use this with your own claim types type StandardClaims struct { - Audience string `json:"aud,omitempty"` - ExpiresAt int64 `json:"exp,omitempty"` - Id string `json:"jti,omitempty"` - IssuedAt int64 `json:"iat,omitempty"` - Issuer string `json:"iss,omitempty"` - NotBefore int64 `json:"nbf,omitempty"` - Subject string `json:"sub,omitempty"` + Audience interface{} `json:"aud,omitempty"` + ExpiresAt int64 `json:"exp,omitempty"` + Id string `json:"jti,omitempty"` + IssuedAt int64 `json:"iat,omitempty"` + Issuer string `json:"iss,omitempty"` + NotBefore int64 `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` } // Validates time based claims "exp, iat, nbf". @@ -61,7 +61,17 @@ func (c StandardClaims) Valid() error { // Compares the aud claim against cmp. // If required is false, this method will return true if the value matches or is unset func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool { - return verifyAud(c.Audience, cmp, req) + var aud []string + if l, ok := c.Audience.([]interface{}); ok { + for _, a := range l { + aud = append(aud, a.(string)) + } + } else if l, ok := c.Audience.([]string); ok { + aud = l + } else if l, ok := c.Audience.(string); ok { + aud = []string{l} + } + return verifyAud(aud, cmp, req) } // Compares the exp claim against cmp. @@ -90,15 +100,16 @@ func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { // ----- helpers -func verifyAud(aud string, cmp string, required bool) bool { - if aud == "" { +func verifyAud(aud []string, cmp string, required bool) bool { + if len(aud) == 0 { return !required } - if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 { - return true - } else { - return false + for _, a := range aud { + if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 { + return true + } } + return false } func verifyExp(exp int64, now int64, required bool) bool { diff --git a/map_claims.go b/map_claims.go index 291213c4..43e996f4 100644 --- a/map_claims.go +++ b/map_claims.go @@ -13,7 +13,16 @@ type MapClaims map[string]interface{} // Compares the aud claim against cmp. // If required is false, this method will return true if the value matches or is unset func (m MapClaims) VerifyAudience(cmp string, req bool) bool { - aud, _ := m["aud"].(string) + var aud []string + if l, ok := m["aud"].([]interface{}); ok { + for _, a := range l { + aud = append(aud, a.(string)) + } + } else if l, ok := m["aud"].([]string); ok { + aud = l + } else if l, ok := m["aud"].(string); ok { + aud = []string{l} + } return verifyAud(aud, cmp, req) } diff --git a/parser_test.go b/parser_test.go index 0c86801b..a01fc6ae 100644 --- a/parser_test.go +++ b/parser_test.go @@ -213,7 +213,7 @@ func TestParser_Parse(t *testing.T) { } if (err == nil && !token.Valid) || (err != nil && token.Valid) { - t.Errorf("[%v] Inconsistent behavior between returned error and token.Valid") + t.Errorf("[%v] Inconsistent behavior between returned error and token.Valid", err) } if data.errors != 0 {