feature: Use RegisteredClaims instead of deprecated staruct StandardClaims (#16206)

Signed-off-by: wujw39640 <wujw39640@hundsun.com>
This commit is contained in:
Adam 2022-08-01 10:23:47 +08:00 committed by GitHub
parent bbc7282c46
commit bf741ad381
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 31 additions and 22 deletions

View File

@ -122,14 +122,14 @@ func MakeToken(ctx context.Context, username, service string, access []*token.Re
now := time.Now().UTC() now := time.Now().UTC()
claims := &v2.Claims{ claims := &v2.Claims{
StandardClaims: jwt.StandardClaims{ RegisteredClaims: jwt.RegisteredClaims{
Issuer: options.Issuer, Issuer: options.Issuer,
Subject: username, Subject: username,
Audience: service, Audience: jwt.ClaimStrings([]string{service}),
ExpiresAt: now.Add(time.Duration(expiration) * time.Minute).Unix(), ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(expiration) * time.Minute)),
NotBefore: now.Unix(), NotBefore: jwt.NewNumericDate(now),
IssuedAt: now.Unix(), IssuedAt: jwt.NewNumericDate(now),
Id: utils.GenerateRandomStringWithLen(16), ID: utils.GenerateRandomStringWithLen(16),
}, },
Access: access, Access: access,
} }

View File

@ -123,7 +123,7 @@ func getPublicKey(crtPath string) (*rsa.PublicKey, error) {
} }
type harborClaims struct { type harborClaims struct {
jwt.StandardClaims jwt.RegisteredClaims
// Private claims // Private claims
Access []*token.ResourceActions `json:"access"` Access []*token.ResourceActions `json:"access"`
} }
@ -160,7 +160,7 @@ func TestMakeToken(t *testing.T) {
} }
claims := tok.Claims.(*harborClaims) claims := tok.Claims.(*harborClaims)
assert.Equal(t, *(claims.Access[0]), *(ra[0]), "Access mismatch") assert.Equal(t, *(claims.Access[0]), *(ra[0]), "Access mismatch")
assert.Equal(t, claims.Audience, svc, "Audience mismatch") assert.Equal(t, claims.Audience, jwt.ClaimStrings([]string{svc}), "Audience mismatch")
} }
type parserTestRec struct { type parserTestRec struct {

View File

@ -8,9 +8,13 @@ import (
"github.com/goharbor/harbor/src/pkg/permission/types" "github.com/goharbor/harbor/src/pkg/permission/types"
) )
func init() {
jwt.MarshalSingleStringAsArray = false
}
// Claim implements the interface of jwt.Claims // Claim implements the interface of jwt.Claims
type Claim struct { type Claim struct {
jwt.StandardClaims jwt.RegisteredClaims
TokenID int64 `json:"id"` TokenID int64 `json:"id"`
ProjectID int64 `json:"pid"` ProjectID int64 `json:"pid"`
Access []*types.Policy `json:"access"` Access []*types.Policy `json:"access"`
@ -27,7 +31,7 @@ func (rc Claim) Valid() error {
if rc.Access == nil { if rc.Access == nil {
return errors.New("the access info cannot be nil") return errors.New("the access info cannot be nil")
} }
stdErr := rc.StandardClaims.Valid() stdErr := rc.RegisteredClaims.Valid()
if stdErr != nil { if stdErr != nil {
return stdErr return stdErr
} }

View File

@ -1,12 +1,17 @@
package v2 package v2
import ( import (
"crypto/subtle"
"fmt" "fmt"
"github.com/docker/distribution/registry/auth/token" "github.com/docker/distribution/registry/auth/token"
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt/v4"
) )
func init() {
jwt.MarshalSingleStringAsArray = false
}
const ( const (
// Issuer is the only valid issuer for jwt token sent to /v2/xxxx // Issuer is the only valid issuer for jwt token sent to /v2/xxxx
Issuer = "harbor-token-issuer" Issuer = "harbor-token-issuer"
@ -14,16 +19,16 @@ const (
// Claims represents the token claims that encapsulated in a JWT token for registry/notary resources // Claims represents the token claims that encapsulated in a JWT token for registry/notary resources
type Claims struct { type Claims struct {
jwt.StandardClaims jwt.RegisteredClaims
Access []*token.ResourceActions `json:"access"` Access []*token.ResourceActions `json:"access"`
} }
// Valid checks if the issuer is harbor // Valid checks if the issuer is harbor
func (c *Claims) Valid() error { func (c *Claims) Valid() error {
if err := c.StandardClaims.Valid(); err != nil { if err := c.RegisteredClaims.Valid(); err != nil {
return err return err
} }
if !c.VerifyIssuer(Issuer, true) { if subtle.ConstantTimeCompare([]byte(c.Issuer), []byte(Issuer)) == 0 {
return fmt.Errorf("invalid token issuer: %s", c.Issuer) return fmt.Errorf("invalid token issuer: %s", c.Issuer)
} }
return nil return nil

View File

@ -15,7 +15,7 @@ func TestValid(t *testing.T) {
}{ }{
{ {
claims: Claims{ claims: Claims{
StandardClaims: jwt.StandardClaims{ RegisteredClaims: jwt.RegisteredClaims{
Issuer: "anonymous", Issuer: "anonymous",
}, },
Access: []*token.ResourceActions{}, Access: []*token.ResourceActions{},
@ -24,7 +24,7 @@ func TestValid(t *testing.T) {
}, },
{ {
claims: Claims{ claims: Claims{
StandardClaims: jwt.StandardClaims{ RegisteredClaims: jwt.RegisteredClaims{
Issuer: Issuer, Issuer: Issuer,
}, },
Access: []*token.ResourceActions{}, Access: []*token.ResourceActions{},

View File

@ -33,13 +33,13 @@ func TestNew(t *testing.T) {
tokenID := int64(123) tokenID := int64(123)
projectID := int64(321) projectID := int64(321)
tokenExpiration := time.Duration(10) * 24 * time.Hour tokenExpiration := time.Duration(10) * 24 * time.Hour
expiresAt := time.Now().UTC().Add(tokenExpiration).Unix() expiresAt := time.Now().UTC().Add(tokenExpiration)
robot := robot_claim.Claim{ robot := robot_claim.Claim{
TokenID: tokenID, TokenID: tokenID,
ProjectID: projectID, ProjectID: projectID,
Access: policies, Access: policies,
StandardClaims: jwt.StandardClaims{ RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: expiresAt, ExpiresAt: jwt.NewNumericDate(expiresAt),
}, },
} }
defaultOpt := DefaultTokenOptions() defaultOpt := DefaultTokenOptions()
@ -60,20 +60,20 @@ func TestRaw(t *testing.T) {
Resource: "/project/library/repository", Resource: "/project/library/repository",
Action: "pull", Action: "pull",
} }
policies := []*types.Policy{} var policies []*types.Policy
policies = append(policies, rbacPolicy) policies = append(policies, rbacPolicy)
tokenID := int64(123) tokenID := int64(123)
projectID := int64(321) projectID := int64(321)
tokenExpiration := time.Duration(10) * 24 * time.Hour tokenExpiration := time.Duration(10) * 24 * time.Hour
expiresAt := time.Now().UTC().Add(tokenExpiration).Unix() expiresAt := time.Now().UTC().Add(tokenExpiration)
robot := robot_claim.Claim{ robot := robot_claim.Claim{
TokenID: tokenID, TokenID: tokenID,
ProjectID: projectID, ProjectID: projectID,
Access: policies, Access: policies,
StandardClaims: jwt.StandardClaims{ RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: expiresAt, ExpiresAt: jwt.NewNumericDate(expiresAt),
}, },
} }
defaultOpt := DefaultTokenOptions() defaultOpt := DefaultTokenOptions()