@@ -29,12 +29,11 @@ import (
2929 "github.com/vouch/vouch-proxy/pkg/structs"
3030)
3131
32- // const numSites = 2
32+ const comma = ","
3333
3434// VouchClaims jwt Claims specific to vouch
3535type VouchClaims struct {
36- Username string `json:"username"`
37- Sites []string `json:"sites"` // tempting to make this a map but the array is fewer characters in the jwt
36+ Username string `json:"username"`
3837 CustomClaims map [string ]interface {}
3938 PAccessToken string
4039 PIdToken string
@@ -44,48 +43,52 @@ type VouchClaims struct {
4443// StandardClaims jwt.StandardClaims implementation
4544var StandardClaims jwt.StandardClaims
4645
47- // CustomClaims implementation
48- // var CustomClaims map[string]interface{}
49-
50- // Sites added to VouchClaims
51- var Sites []string
5246var logger * zap.Logger
5347var log * zap.SugaredLogger
48+ var aud string
5449
5550// Configure see main.go configure()
5651func Configure () {
5752 log = cfg .Logging .Logger
5853 logger = cfg .Logging .FastLogger
5954 cacheConfigure ()
55+ aud = audience ()
6056 StandardClaims = jwt.StandardClaims {
61- Issuer : cfg .Cfg .JWT .Issuer ,
57+ Issuer : cfg .Cfg .JWT .Issuer ,
58+ Audience : aud ,
6259 }
63- populateSites ()
6460}
6561
66- func populateSites () {
67- Sites = make ([]string , 0 )
62+ // `aud` of the issued JWT https://tools.ietf.org/html/rfc7519#section-4.1.3
63+ func audience () string {
64+ aud := make ([]string , 0 )
6865 // TODO: the Sites that end up in the JWT come from here
6966 // if we add fine grain ability (ACL?) to the equation
7067 // then we're going to have to add something fancier here
7168 for i := 0 ; i < len (cfg .Cfg .Domains ); i ++ {
72- Sites = append (Sites , cfg .Cfg .Domains [i ])
69+ aud = append (aud , cfg .Cfg .Domains [i ])
70+ }
71+ if cfg .Cfg .Cookie .Domain != "" {
72+ aud = append (aud , cfg .Cfg .Cookie .Domain )
7373 }
74+ return strings .Join (aud , comma )
7475}
7576
76- // CreateUserTokenString converts user to signed jwt
77- func CreateUserTokenString (u structs.User , customClaims structs.CustomClaims , ptokens structs.PTokens ) string {
77+ // NewVPJWT issue a signed Vouch Proxy JWT for a user
78+ func NewVPJWT (u structs.User , customClaims structs.CustomClaims , ptokens structs.PTokens ) ( string , error ) {
7879 // User`token`
7980 // u.PrepareUserData()
8081 claims := VouchClaims {
8182 u .Username ,
82- Sites ,
8383 customClaims .Claims ,
8484 ptokens .PAccessToken ,
8585 ptokens .PIdToken ,
8686 StandardClaims ,
8787 }
8888
89+ claims .Audience = aud
90+ claims .ExpiresAt = time .Now ().Add (time .Minute * time .Duration (cfg .Cfg .JWT .MaxAge )).Unix ()
91+
8992 // https://github.com/vouch/vouch-proxy/issues/287
9093 if cfg .Cfg .Headers .AccessToken == "" {
9194 claims .PAccessToken = ""
@@ -95,8 +98,6 @@ func CreateUserTokenString(u structs.User, customClaims structs.CustomClaims, pt
9598 claims .PIdToken = ""
9699 }
97100
98- claims .StandardClaims .ExpiresAt = time .Now ().Add (time .Minute * time .Duration (cfg .Cfg .JWT .MaxAge )).Unix ()
99-
100101 // https://godoc.org/github.com/dgrijalva/jwt-go#NewWithClaims
101102 token := jwt .NewWithClaims (jwt .GetSigningMethod ("HS256" ), claims )
102103
@@ -107,15 +108,15 @@ func CreateUserTokenString(u structs.User, customClaims structs.CustomClaims, pt
107108 ss , err := token .SignedString ([]byte (cfg .Cfg .JWT .Secret ))
108109 // ss, err := token.SignedString([]byte("testing"))
109110 if ss == "" || err != nil {
110- log .Errorf ("signed token error: %s" , err )
111+ return "" , fmt .Errorf ("New JWT: signed token error: %s" , err )
111112 }
112113 if cfg .Cfg .JWT .Compress {
113114 ss , err = compressAndEncodeTokenString (ss )
114115 if ss == "" || err != nil {
115- log .Errorf ("compressed token error: %s " , err )
116+ return "" , fmt .Errorf ("New JWT: compressed token error: %w " , err )
116117 }
117118 }
118- return ss
119+ return ss , nil
119120}
120121
121122// TokenIsValid gett better error reporting
@@ -141,11 +142,11 @@ func TokenIsValid(token *jwt.Token, err error) bool {
141142func SiteInToken (site string , token * jwt.Token ) bool {
142143 if claims , ok := token .Claims .(* VouchClaims ); ok {
143144 log .Debugf ("site %s claim %v" , site , claims )
144- if claims .SiteInClaims (site ) {
145+ if claims .SiteInAudience (site ) {
145146 return true
146147 }
147148 }
148- log .Errorf ("site %s not found in token" , site )
149+ log .Errorf ("site %s not found in token audience " , site )
149150 return false
150151}
151152
@@ -168,11 +169,11 @@ func ParseTokenString(tokenString string) (*jwt.Token, error) {
168169
169170}
170171
171- // SiteInClaims does the claim contain the value?
172- func (claims * VouchClaims ) SiteInClaims (site string ) bool {
173- for _ , s := range claims . Sites {
172+ // SiteInAudience does the claim contain the value?
173+ func (claims * VouchClaims ) SiteInAudience (site string ) bool {
174+ for _ , s := range strings . Split ( aud , comma ) {
174175 if strings .Contains (site , s ) {
175- log .Debugf ("site %s is found for claims.Site %s" , site , s )
176+ log .Debugf ("site %s is found for claims.Audience %s" , site , s )
176177 return true
177178 }
178179 }
0 commit comments