Skip to content

Commit 45b6d32

Browse files
committed
init
1 parent 854f7a3 commit 45b6d32

File tree

5 files changed

+1703
-0
lines changed

5 files changed

+1703
-0
lines changed

caddyfile.go

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package caddyjwt
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/caddyserver/caddy/v2"
8+
"github.com/caddyserver/caddy/v2/caddyconfig"
9+
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
10+
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
11+
"github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth"
12+
)
13+
14+
func init() {
15+
httpcaddyfile.RegisterHandlerDirective("jwtauth", parseCaddyfile)
16+
}
17+
18+
// parseCaddyfile sets up the handler from Caddyfile. Syntax:
19+
//
20+
// jwtauth [<matcher>] {
21+
// sign_key <sign_key>
22+
// ...
23+
// }
24+
func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
25+
var ja JWTAuth
26+
27+
for h.Next() {
28+
for h.NextBlock(0) {
29+
opt := h.Val()
30+
switch opt {
31+
case "sign_key":
32+
if !h.AllArgs(&ja.SignKey) {
33+
return nil, h.Errf("invalid sign_key: %q", ja.SignKey)
34+
}
35+
case "sign_alg":
36+
if !h.AllArgs(&ja.SignAlgorithm) {
37+
return nil, h.Errf("invalid sign_alg: %q", ja.SignAlgorithm)
38+
}
39+
case "jwk_url":
40+
if !h.AllArgs(&ja.JWKURL) {
41+
return nil, h.Errf("invalid jwk_url: %q", ja.JWKURL)
42+
}
43+
case "from_query":
44+
ja.FromQuery = h.RemainingArgs()
45+
46+
case "from_header":
47+
ja.FromHeader = h.RemainingArgs()
48+
49+
case "from_cookies":
50+
ja.FromCookies = h.RemainingArgs()
51+
52+
case "audience_whitelist":
53+
ja.AudienceWhitelist = h.RemainingArgs()
54+
55+
case "issuer_whitelist":
56+
ja.IssuerWhitelist = h.RemainingArgs()
57+
58+
case "user_claims":
59+
ja.UserClaims = h.RemainingArgs()
60+
61+
case "meta_claims":
62+
ja.MetaClaims = make(map[string]string)
63+
for _, metaClaim := range h.RemainingArgs() {
64+
claim, placeholder, err := parseMetaClaim(metaClaim)
65+
if err != nil {
66+
return nil, h.Errf("invalid meta_claims: %w", err)
67+
}
68+
if _, ok := ja.MetaClaims[claim]; ok {
69+
return nil, h.Errf("invalid meta_claims: duplicate claim: %s", claim)
70+
}
71+
ja.MetaClaims[claim] = placeholder
72+
}
73+
case "header_first":
74+
return nil, h.Err("option header_first deprecated, the priority now defaults to from_query > from_header > from_cookies")
75+
76+
default:
77+
return nil, h.Errf("unrecognized option: %s", opt)
78+
}
79+
}
80+
}
81+
82+
return caddyauth.Authentication{
83+
ProvidersRaw: caddy.ModuleMap{
84+
"jwt": caddyconfig.JSON(ja, nil),
85+
},
86+
}, nil
87+
}
88+
89+
// parseMetaClaim parses key to get the claim and corresponding placeholder.
90+
// e.g "IsAdmin -> is_admin" as { Claim: "IsAdmin", Placeholder: "is_admin" }.
91+
func parseMetaClaim(key string) (claim, placeholder string, err error) {
92+
parts := strings.Split(key, "->")
93+
if len(parts) == 1 {
94+
claim = strings.TrimSpace(parts[0])
95+
placeholder = strings.TrimSpace(parts[0])
96+
} else if len(parts) == 2 {
97+
claim = strings.TrimSpace(parts[0])
98+
placeholder = strings.TrimSpace(parts[1])
99+
} else {
100+
return "", "", fmt.Errorf("too many delimiters (->) in key %q", key)
101+
}
102+
103+
if claim == "" {
104+
return "", "", fmt.Errorf("empty claim in key %q", key)
105+
}
106+
if placeholder == "" {
107+
return "", "", fmt.Errorf("empty placeholder in key %q", key)
108+
}
109+
return
110+
}

errors.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package caddyjwt
2+
3+
import "errors"
4+
5+
var (
6+
ErrMissingKeys = errors.New("missing sign_key and jwk_url")
7+
ErrInvalidPublicKey = errors.New("invalid PEM-formatted public key")
8+
ErrInvalidSignAlgorithm = errors.New("invalid sign_alg")
9+
ErrInvalidIssuer = errors.New("invalid issuer")
10+
ErrInvalidAudience = errors.New("invalid audience")
11+
ErrEmptyUserClaim = errors.New("user claim is empty")
12+
)

go.mod

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
module github.com/liuzhen21/caddy-jwt
2+
3+
go 1.20
4+
5+
require (
6+
github.com/caddyserver/caddy/v2 v2.7.4
7+
github.com/golang-jwt/jwt v3.2.2+incompatible
8+
github.com/lestrrat-go/jwx/v2 v2.0.13
9+
go.uber.org/zap v1.26.0
10+
)
11+
12+
require (
13+
filippo.io/edwards25519 v1.0.0 // indirect
14+
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
15+
github.com/Masterminds/goutils v1.1.1 // indirect
16+
github.com/Masterminds/semver/v3 v3.2.0 // indirect
17+
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
18+
github.com/Microsoft/go-winio v0.6.0 // indirect
19+
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
20+
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect
21+
github.com/beorn7/perks v1.0.1 // indirect
22+
github.com/caddyserver/certmagic v0.19.2 // indirect
23+
github.com/cespare/xxhash v1.1.0 // indirect
24+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
25+
github.com/chzyer/readline v1.5.1 // indirect
26+
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
27+
github.com/dgraph-io/badger v1.6.2 // indirect
28+
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
29+
github.com/dgraph-io/ristretto v0.1.0 // indirect
30+
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
31+
github.com/dustin/go-humanize v1.0.1 // indirect
32+
github.com/go-kit/kit v0.10.0 // indirect
33+
github.com/go-logfmt/logfmt v0.5.1 // indirect
34+
github.com/go-sql-driver/mysql v1.7.0 // indirect
35+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
36+
github.com/golang/glog v1.1.0 // indirect
37+
github.com/golang/mock v1.6.0 // indirect
38+
github.com/golang/protobuf v1.5.3 // indirect
39+
github.com/golang/snappy v0.0.4 // indirect
40+
github.com/google/cel-go v0.15.1 // indirect
41+
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
42+
github.com/google/uuid v1.3.0 // indirect
43+
github.com/huandu/xstrings v1.3.3 // indirect
44+
github.com/imdario/mergo v0.3.12 // indirect
45+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
46+
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
47+
github.com/jackc/pgconn v1.14.0 // indirect
48+
github.com/jackc/pgio v1.0.0 // indirect
49+
github.com/jackc/pgpassfile v1.0.0 // indirect
50+
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
51+
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
52+
github.com/jackc/pgtype v1.14.0 // indirect
53+
github.com/jackc/pgx/v4 v4.18.0 // indirect
54+
github.com/klauspost/compress v1.16.7 // indirect
55+
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
56+
github.com/libdns/libdns v0.2.1 // indirect
57+
github.com/manifoldco/promptui v0.9.0 // indirect
58+
github.com/mattn/go-colorable v0.1.8 // indirect
59+
github.com/mattn/go-isatty v0.0.16 // indirect
60+
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
61+
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
62+
github.com/mholt/acmez v1.2.0 // indirect
63+
github.com/micromdm/scep/v2 v2.1.0 // indirect
64+
github.com/miekg/dns v1.1.55 // indirect
65+
github.com/mitchellh/copystructure v1.2.0 // indirect
66+
github.com/mitchellh/go-ps v1.0.0 // indirect
67+
github.com/mitchellh/reflectwalk v1.0.2 // indirect
68+
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
69+
github.com/pkg/errors v0.9.1 // indirect
70+
github.com/prometheus/client_golang v1.14.0 // indirect
71+
github.com/prometheus/client_model v0.3.0 // indirect
72+
github.com/prometheus/common v0.37.0 // indirect
73+
github.com/prometheus/procfs v0.8.0 // indirect
74+
github.com/quic-go/qpack v0.4.0 // indirect
75+
github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
76+
github.com/quic-go/quic-go v0.37.5 // indirect
77+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
78+
github.com/shopspring/decimal v1.2.0 // indirect
79+
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
80+
github.com/slackhq/nebula v1.6.1 // indirect
81+
github.com/smallstep/certificates v0.24.3-rc.5 // indirect
82+
github.com/smallstep/nosql v0.6.0 // indirect
83+
github.com/smallstep/truststore v0.12.1 // indirect
84+
github.com/spf13/cast v1.4.1 // indirect
85+
github.com/spf13/cobra v1.7.0 // indirect
86+
github.com/spf13/pflag v1.0.5 // indirect
87+
github.com/stoewer/go-strcase v1.2.0 // indirect
88+
github.com/tailscale/tscert v0.0.0-20230509043813-4e9cb4f2b4ad // indirect
89+
github.com/urfave/cli v1.22.14 // indirect
90+
github.com/zeebo/blake3 v0.2.3 // indirect
91+
go.etcd.io/bbolt v1.3.7 // indirect
92+
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
93+
go.step.sm/cli-utils v0.8.0 // indirect
94+
go.step.sm/crypto v0.33.0 // indirect
95+
go.step.sm/linkedca v0.20.0 // indirect
96+
go.uber.org/multierr v1.11.0 // indirect
97+
golang.org/x/crypto v0.13.0 // indirect
98+
golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 // indirect
99+
golang.org/x/mod v0.11.0 // indirect
100+
golang.org/x/net v0.14.0 // indirect
101+
golang.org/x/sync v0.3.0 // indirect
102+
golang.org/x/sys v0.12.0 // indirect
103+
golang.org/x/term v0.12.0 // indirect
104+
golang.org/x/text v0.13.0 // indirect
105+
golang.org/x/tools v0.10.0 // indirect
106+
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect
107+
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
108+
google.golang.org/grpc v1.56.2 // indirect
109+
google.golang.org/protobuf v1.31.0 // indirect
110+
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
111+
gopkg.in/yaml.v3 v3.0.1 // indirect
112+
howett.net/plist v1.0.0 // indirect
113+
)

0 commit comments

Comments
 (0)