@@ -29,13 +29,12 @@ 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- Sub string `json:"sub"`
37- Username string `json:"username"`
38- Sites []string `json:"sites"` // tempting to make this a map but the array is fewer characters in the jwt
36+ Sub string `json:"sub"`
37+ Username string `json:"username"`
3938 CustomClaims map [string ]interface {}
4039 PAccessToken string
4140 PIdToken string
@@ -45,49 +44,53 @@ type VouchClaims struct {
4544// StandardClaims jwt.StandardClaims implementation
4645var StandardClaims jwt.StandardClaims
4746
48- // CustomClaims implementation
49- // var CustomClaims map[string]interface{}
50-
51- // Sites added to VouchClaims
52- var Sites []string
5347var logger * zap.Logger
5448var log * zap.SugaredLogger
49+ var aud string
5550
5651// Configure see main.go configure()
5752func Configure () {
5853 log = cfg .Logging .Logger
5954 logger = cfg .Logging .FastLogger
6055 cacheConfigure ()
56+ aud = audience ()
6157 StandardClaims = jwt.StandardClaims {
62- Issuer : cfg .Cfg .JWT .Issuer ,
58+ Issuer : cfg .Cfg .JWT .Issuer ,
59+ Audience : aud ,
6360 }
64- populateSites ()
6561}
6662
67- func populateSites () {
68- Sites = make ([]string , 0 )
63+ // `aud` of the issued JWT https://tools.ietf.org/html/rfc7519#section-4.1.3
64+ func audience () string {
65+ aud := make ([]string , 0 )
6966 // TODO: the Sites that end up in the JWT come from here
7067 // if we add fine grain ability (ACL?) to the equation
7168 // then we're going to have to add something fancier here
7269 for i := 0 ; i < len (cfg .Cfg .Domains ); i ++ {
73- Sites = append (Sites , cfg .Cfg .Domains [i ])
70+ aud = append (aud , cfg .Cfg .Domains [i ])
71+ }
72+ if cfg .Cfg .Cookie .Domain != "" {
73+ aud = append (aud , cfg .Cfg .Cookie .Domain )
7474 }
75+ return strings .Join (aud , comma )
7576}
7677
77- // CreateUserTokenString converts user to signed jwt
78- func CreateUserTokenString (u structs.User , customClaims structs.CustomClaims , ptokens structs.PTokens ) string {
78+ // NewVPJWT issue a signed Vouch Proxy JWT for a user
79+ func NewVPJWT (u structs.User , customClaims structs.CustomClaims , ptokens structs.PTokens ) ( string , error ) {
7980 // User`token`
8081 // u.PrepareUserData()
8182 claims := VouchClaims {
8283 u .Sub ,
8384 u .Username ,
84- Sites ,
8585 customClaims .Claims ,
8686 ptokens .PAccessToken ,
8787 ptokens .PIdToken ,
8888 StandardClaims ,
8989 }
9090
91+ claims .Audience = aud
92+ claims .ExpiresAt = time .Now ().Add (time .Minute * time .Duration (cfg .Cfg .JWT .MaxAge )).Unix ()
93+
9194 // https://github.com/vouch/vouch-proxy/issues/287
9295 if cfg .Cfg .Headers .AccessToken == "" {
9396 claims .PAccessToken = ""
@@ -97,8 +100,6 @@ func CreateUserTokenString(u structs.User, customClaims structs.CustomClaims, pt
97100 claims .PIdToken = ""
98101 }
99102
100- claims .StandardClaims .ExpiresAt = time .Now ().Add (time .Minute * time .Duration (cfg .Cfg .JWT .MaxAge )).Unix ()
101-
102103 // https://godoc.org/github.com/dgrijalva/jwt-go#NewWithClaims
103104 token := jwt .NewWithClaims (jwt .GetSigningMethod ("HS256" ), claims )
104105
@@ -109,15 +110,15 @@ func CreateUserTokenString(u structs.User, customClaims structs.CustomClaims, pt
109110 ss , err := token .SignedString ([]byte (cfg .Cfg .JWT .Secret ))
110111 // ss, err := token.SignedString([]byte("testing"))
111112 if ss == "" || err != nil {
112- log .Errorf ("signed token error: %s" , err )
113+ return "" , fmt .Errorf ("New JWT: signed token error: %s" , err )
113114 }
114115 if cfg .Cfg .JWT .Compress {
115116 ss , err = compressAndEncodeTokenString (ss )
116117 if ss == "" || err != nil {
117- log .Errorf ("compressed token error: %s " , err )
118+ return "" , fmt .Errorf ("New JWT: compressed token error: %w " , err )
118119 }
119120 }
120- return ss
121+ return ss , nil
121122}
122123
123124// TokenIsValid gett better error reporting
@@ -143,11 +144,11 @@ func TokenIsValid(token *jwt.Token, err error) bool {
143144func SiteInToken (site string , token * jwt.Token ) bool {
144145 if claims , ok := token .Claims .(* VouchClaims ); ok {
145146 log .Debugf ("site %s claim %v" , site , claims )
146- if claims .SiteInClaims (site ) {
147+ if claims .SiteInAudience (site ) {
147148 return true
148149 }
149150 }
150- log .Errorf ("site %s not found in token" , site )
151+ log .Errorf ("site %s not found in token audience " , site )
151152 return false
152153}
153154
@@ -170,11 +171,11 @@ func ParseTokenString(tokenString string) (*jwt.Token, error) {
170171
171172}
172173
173- // SiteInClaims does the claim contain the value?
174- func (claims * VouchClaims ) SiteInClaims (site string ) bool {
175- for _ , s := range claims . Sites {
174+ // SiteInAudience does the claim contain the value?
175+ func (claims * VouchClaims ) SiteInAudience (site string ) bool {
176+ for _ , s := range strings . Split ( aud , comma ) {
176177 if strings .Contains (site , s ) {
177- log .Debugf ("site %s is found for claims.Site %s" , site , s )
178+ log .Debugf ("site %s is found for claims.Audience %s" , site , s )
178179 return true
179180 }
180181 }
0 commit comments