func VerifyClaims(jwt jose.JWT, issuer, clientID string) error {
	now := time.Now().UTC()
	claims, err := jwt.Claims()
	if err != nil {
		return err
	}
	ident, err := IdentityFromClaims(claims)
	if err != nil {
		return err
	}
	if ident.ExpiresAt.Before(now) {
		return errors.New("token is expired")
	}
	if iss, exists := claims["iss"].(string); exists {
		if !urlEqual(iss, issuer) {
			return fmt.Errorf("invalid claim value: 'iss'. expected=%s, found=%s.", issuer, iss)
		}
	} else {
		return errors.New("missing claim: 'iss'")
	}
	if _, exists := claims["iat"].(float64); !exists {
		return errors.New("missing claim: 'iat'")
	}
	if aud, ok, err := claims.StringClaim("aud"); err == nil && ok {
		if aud != clientID {
			return fmt.Errorf("invalid claims, 'aud' claim and 'client_id' do not match, aud=%s, client_id=%s", aud, clientID)
		}
	} else if aud, ok, err := claims.StringsClaim("aud"); err == nil && ok {
		if !containsString(clientID, aud) {
			return fmt.Errorf("invalid claims, cannot find 'client_id' in 'aud' claim, aud=%v, client_id=%s", aud, clientID)
		}
	} else {
		return errors.New("invalid claim value: 'aud' is required, and should be either string or string array")
	}
	return nil
}
Verify claims in accordance with OIDC spec
http://openid.net/specs/openid-connect-basic-1_0.html#IDTokenValidation
package oidc
import (
	"errors"
	"fmt"
	"time"
	"github.com/jonboulle/clockwork"
	"github.com/coreos/go-oidc/jose"
	"github.com/coreos/go-oidc/key"
)
func VerifySignature(jwt jose.JWT, keys []key.PublicKey) (bool, error) {
	jwtBytes := []byte(jwt.Data())
	for _, k := range keys {
		v, err := k.Verifier()
		if err != nil {
			return false, err
		}
		if v.Verify(jwt.Signature, jwtBytes) == nil {
			return true, nil
		}
	}
	return false, nil
}
func containsString(needle string, haystack []string) bool {
	for _, v := range haystack {
		if v == needle {
			return true
		}
	}
	return false
}