feat: accept lists in the token audience claim
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
This commit is contained in:
parent
97fa1183bf
commit
3472f7a8e3
4 changed files with 35 additions and 22 deletions
|
@ -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(),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue