Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 9bba460

Browse files
committed
Transfer JWT claims to CGI environment variables
1 parent d8c8894 commit 9bba460

File tree

7 files changed

+110
-10
lines changed

7 files changed

+110
-10
lines changed

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,27 @@ the response looks the same except for the following lines:
263263
POST_DATA [city=San%20Francisco]
264264
REQUEST_METHOD [POST]
265265

266+
### JSON web tokens
267+
268+
If you protect your CGI application with the [Caddy JWT][jwt] middleware, your
269+
program will have access to the token's payload claims by means of environment
270+
variables. For example, the following token claims
271+
272+
{
273+
"sub": "1234567890",
274+
"user": "quixote",
275+
"admin": true,
276+
}
277+
278+
will be available with the following environment variables
279+
280+
HTTP_TOKEN_CLAIM_SUB=1234567890
281+
HTTP_TOKEN_CLAIM_USER=doe
282+
HTTP_TOKEN_CLAIM_ADMIN=true
283+
284+
All values are conveyed as strings, so some conversion may be necessary in your
285+
program.
286+
266287
### Fossil Example
267288

268289
The [fossil][fossil] distributed software management tool is a native
@@ -466,10 +487,11 @@ at sample/min.php:
466487
[fossil]: https://www.fossil-scm.org/
467488
[github]: https://github.com/jung-kurt/caddy-cgi
468489
[jung]: https://github.com/jung-kurt/
490+
[jwt]: https://github.com/BTBurke/caddy-jwt
469491
[key]: class:key
470-
[subkey]: class:subkey
471492
[license]: https://raw.githubusercontent.com/jung-kurt/caddy-cgi/master/LICENSE
472493
[match]: https://golang.org/pkg/path/#Match
473494
[php]: http://php.net/
474495
[report]: https://goreportcard.com/report/github.com/jung-kurt/caddy-cgi
496+
[subkey]: class:subkey
475497
[travis]: https://travis-ci.org/jung-kurt/caddy-cgi

cgi.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"net/http/cgi"
2424
"path"
2525
"path/filepath"
26+
"strings"
2627

2728
"github.com/mholt/caddy/caddyhttp/httpserver"
2829
)
@@ -62,7 +63,7 @@ func currentDir() (wdStr string) {
6263
// setupCall instantiates a CGI handler based on the incoming request and the
6364
// configuration rule that it matches.
6465
func setupCall(h handlerType, rule ruleType, lfStr, rtStr string,
65-
rep httpserver.Replacer, username string) (cgiHnd cgi.Handler) {
66+
rep httpserver.Replacer, hdr http.Header, username string) (cgiHnd cgi.Handler) {
6667
cgiHnd.Root = "/"
6768
cgiHnd.Dir = h.root
6869
rep.Set("root", h.root)
@@ -86,6 +87,13 @@ func setupCall(h handlerType, rule ruleType, lfStr, rtStr string,
8687
envAdd("PATH_INFO", rtStr)
8788
envAdd("SCRIPT_FILENAME", cgiHnd.Path)
8889
envAdd("SCRIPT_NAME", lfStr)
90+
// Convey JSON Web Token claims to CGI app by means of environment
91+
for key, list := range hdr {
92+
if strings.HasPrefix(key, "Token-Claim-") {
93+
cgiHnd.Env = append(cgiHnd.Env, strings.ToUpper(key)+"="+
94+
strings.Join(list, "\t"))
95+
}
96+
}
8997
cgiHnd.InheritEnv = append(cgiHnd.InheritEnv, rule.passEnvs...)
9098
cgiHnd.InheritEnv = append(cgiHnd.InheritEnv, rule.passEnvs...)
9199
for _, str := range rule.args {
@@ -106,7 +114,7 @@ func (h handlerType) ServeHTTP(w http.ResponseWriter, r *http.Request) (code int
106114
// Retrieve name of remote user that was set by some downstream middleware,
107115
// possibly basicauth.
108116
remoteUser, _ := r.Context().Value(httpserver.RemoteUserCtxKey).(string) // Blank if not set
109-
cgiHnd := setupCall(h, rule, lfStr, rtStr, rep, remoteUser)
117+
cgiHnd := setupCall(h, rule, lfStr, rtStr, rep, r.Header, remoteUser)
110118
cgiHnd.Stderr = &buf
111119
cgiHnd.ServeHTTP(w, r)
112120
if buf.Len() > 0 {

cgi_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ func TestServe(t *testing.T) {
6464
}
6565

6666
expectStr := `code [0], error [example error message]
67-
[ ]
67+
[---] [---] [---] [quixote] [] []
6868
code [0], error [example error message]
69-
[/1930/05/11 name=Edsger%20W.%20Dijkstra ]
69+
[/1930/05/11] [---] [---] [---] [name=Edsger%20W.%20Dijkstra] [quixote]
7070
code [0], error [example error message]
71-
[12 --example ]
71+
[---] [12] [--example] [quixote] [] []
7272
code [0], error [example error message]
73-
[/1930/05/11 12 --example name=Edsger%20W.%20Dijkstra ]
73+
[/1930/05/11] [---] [12] [--example] [name=Edsger%20W.%20Dijkstra] [quixote]
7474
`
75+
7576
// Testing the ServeHTTP method requires OS-specific CGI scripts, because a
7677
// system call is made to respond to the request.
7778
if runtime.GOOS == "linux" || runtime.GOOS == "darwin" {
@@ -80,6 +81,9 @@ code [0], error [example error message]
8081
hnd, err = handlerGet(directiveList[dirJ], "./test")
8182
if err == nil {
8283
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
84+
r.Header.Set("Token-Claim-User", "quixote")
85+
r.Header.Set("Token-Claim-Language", "en-GB")
86+
r.Header.Add("Token-Claim-Language", "en-AU")
8387
code, err = hnd.ServeHTTP(w, r)
8488
if err != nil {
8589
fmt.Fprintf(&buf, "code [%d], error [%s]\n", code, err)

doc.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,27 @@ the response looks the same except for the following lines:
260260
POST_DATA [city=San%20Francisco]
261261
REQUEST_METHOD [POST]
262262
263+
JSON web tokens
264+
265+
If you protect your CGI application with the Caddy JWT middleware, your
266+
program will have access to the token's payload claims by means of environment
267+
variables. For example, the following token claims
268+
269+
{
270+
"sub": "1234567890",
271+
"user": "quixote",
272+
"admin": true,
273+
}
274+
275+
will be available with the following environment variables
276+
277+
HTTP_TOKEN_CLAIM_SUB=1234567890
278+
HTTP_TOKEN_CLAIM_USER=doe
279+
HTTP_TOKEN_CLAIM_ADMIN=true
280+
281+
All values are conveyed as strings, so some conversion may be necessary in your
282+
program.
283+
263284
Fossil Example
264285
265286
The fossil distributed software management tool is a native

doc/cgi.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,27 @@ the response looks the same except for the following lines:
266266
POST_DATA [city=San%20Francisco]
267267
REQUEST_METHOD [POST]
268268

269+
### JSON web tokens
270+
271+
If you protect your CGI application with the [Caddy JWT][jwt] middleware, your
272+
program will have access to the token's payload claims by means of environment
273+
variables. For example, the following token claims
274+
275+
{
276+
"sub": "1234567890",
277+
"user": "quixote",
278+
"admin": true,
279+
}
280+
281+
will be available with the following environment variables
282+
283+
HTTP_TOKEN_CLAIM_SUB=1234567890
284+
HTTP_TOKEN_CLAIM_USER=doe
285+
HTTP_TOKEN_CLAIM_ADMIN=true
286+
287+
All values are conveyed as strings, so some conversion may be necessary in your
288+
program.
289+
269290
### Fossil Example
270291

271292
The [fossil][fossil] distributed software management tool is a native
@@ -469,10 +490,11 @@ at sample/min.php:
469490
[fossil]: https://www.fossil-scm.org/
470491
[github]: https://github.com/jung-kurt/caddy-cgi
471492
[jung]: https://github.com/jung-kurt/
493+
[jwt]: https://github.com/BTBurke/caddy-jwt
472494
[key]: class:key
473-
[subkey]: class:subkey
474495
[license]: https://raw.githubusercontent.com/jung-kurt/caddy-cgi/master/LICENSE
475496
[match]: https://golang.org/pkg/path/#Match
476497
[php]: http://php.net/
477498
[report]: https://goreportcard.com/report/github.com/jung-kurt/caddy-cgi
499+
[subkey]: class:subkey
478500
[travis]: https://travis-ci.org/jung-kurt/caddy-cgi

doc/doc.txt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,27 @@ the response looks the same except for the following lines:
303303
POST_DATA [city=San%20Francisco]
304304
REQUEST_METHOD [POST]
305305

306+
### JSON web tokens
307+
308+
If you protect your CGI application with the [Caddy JWT][jwt] middleware, your
309+
program will have access to the token's payload claims by means of environment
310+
variables. For example, the following token claims
311+
312+
{
313+
"sub": "1234567890",
314+
"user": "quixote",
315+
"admin": true,
316+
}
317+
318+
will be available with the following environment variables
319+
320+
HTTP_TOKEN_CLAIM_SUB=1234567890
321+
HTTP_TOKEN_CLAIM_USER=doe
322+
HTTP_TOKEN_CLAIM_ADMIN=true
323+
324+
All values are conveyed as strings, so some conversion may be necessary in your
325+
program.
326+
306327
### Fossil Example
307328

308329
The [fossil][fossil] distributed software management tool is a native
@@ -507,10 +528,11 @@ at sample/min.php:
507528
[fossil]: https://www.fossil-scm.org/
508529
[github]: https://github.com/jung-kurt/caddy-cgi
509530
[jung]: https://github.com/jung-kurt/
531+
[jwt]: https://github.com/BTBurke/caddy-jwt
510532
[key]: class:key
511-
[subkey]: class:subkey
512533
[license]: https://raw.githubusercontent.com/jung-kurt/caddy-cgi/master/LICENSE
513534
[match]: https://golang.org/pkg/path/#Match
514535
[php]: http://php.net/
515536
[report]: https://goreportcard.com/report/github.com/jung-kurt/caddy-cgi
537+
[subkey]: class:subkey
516538
[travis]: https://travis-ci.org/jung-kurt/caddy-cgi

test/example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22

33
printf "Content-type: text/plain\n\n"
4-
printf "[%s %s %s %s %s]\n" $PATH_INFO $CGI_LOCAL $CGI_GLOBAL $1 $QUERY_STRING
4+
printf "[%s] [%s] [%s] [%s] [%s] [%s]\n" ${PATH_INFO----} ${CGI_LOCAL----} \
5+
${CGI_GLOBAL----} ${1----} ${QUERY_STRING----} ${HTTP_TOKEN_CLAIM_USER----}
56
printf "example error message\n" > /dev/stderr
67
exit 0

0 commit comments

Comments
 (0)