This repository has been archived by the owner on Mar 18, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontentValidation.go
163 lines (133 loc) · 4.17 KB
/
contentValidation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package jwt
import (
"encoding/json"
"errors"
"time"
)
// ExpiresValidationProvider can be used to validate that the token is currently valid.
// It can be initialized with a tolerance that can compensate for slight differences in clocks.
type ExpiresValidationProvider struct {
Tolerance int64
}
// Validate will be called during validation of a token
func (p ExpiresValidationProvider) Validate(c []byte) error {
var exp struct {
Expires int64 `json:"exp"`
}
if err := json.Unmarshal(c, &exp); err != nil {
return err
}
if time.Unix(exp.Expires+p.Tolerance, 0).Before(time.Now().UTC()) {
return errors.New("jwt has expired")
}
return nil
}
// NotBeforeValidationProvider can be used to validate that the token is currently valid.
// It can be initialized with a tolerance that can compensate for slight differences in clocks.
type NotBeforeValidationProvider struct {
Tolerance int64
}
// Validate will be called during validation of a token
func (p NotBeforeValidationProvider) Validate(c []byte) error {
var nbf struct {
NotBefore int64 `json:"nbf"`
}
if err := json.Unmarshal(c, &nbf); err != nil {
return err
}
if time.Unix(nbf.NotBefore-p.Tolerance, 0).After(time.Now().UTC()) {
return errors.New("jwt is not valid, yet")
}
return nil
}
// IssuedAtValidationProvider can be used that the token has been issued in a specific timeframe.
// It should be initialized with an amount of seconds after which tokens expire and optionally also a tolerance.
// Important: This provider also checks whether issued at timestamp is in the future and returns an error in that case.
type IssuedAtValidationProvider struct {
Tolerance int64
ExpiresAfter int64
}
// Validate will be called during validation of a token
func (p IssuedAtValidationProvider) Validate(c []byte) error {
var iat struct {
IssuedAt int64 `json:"iat"`
}
if err := json.Unmarshal(c, &iat); err != nil {
return err
}
if time.Unix(iat.IssuedAt+p.ExpiresAfter+p.Tolerance, 0).Before(time.Now().UTC()) {
return errors.New("jwt has expired")
}
if time.Unix(iat.IssuedAt-p.Tolerance, 0).After(time.Now().UTC()) {
return errors.New("jwt is not valid, yet")
}
return nil
}
// IssuerValidationProvider validates the issuer of a JWT.
// It should be initialized with a slice of issuers.
// By default it considers the slice a blacklist. This can be changed by setting whilelist to true.
type IssuerValidationProvider struct {
Issuers []string
Whitelist bool
}
// Validate will be called during validation of a token
func (p IssuerValidationProvider) Validate(c []byte) error {
var iss struct {
Issuer string `json:"iss"`
}
if err := json.Unmarshal(c, &iss); err != nil {
return err
}
if p.Whitelist {
for _, issuer := range p.Issuers {
if iss.Issuer == issuer {
return nil
}
}
return errors.New("issuer is not on whitelist")
}
for _, issuer := range p.Issuers {
if iss.Issuer == issuer {
return errors.New("issuer is on blacklist")
}
}
return nil
}
// AudienceValidationProvider checks whether the token is for the correct audience.
// It should be initialized with an expected audience and will return an error when a different audience is encountered.
type AudienceValidationProvider struct {
ExpectedAudience string
}
// Validate will be called during validation of a token
func (p AudienceValidationProvider) Validate(c []byte) error {
var aud struct {
Audience string `json:"aud"`
}
if err := json.Unmarshal(c, &aud); err != nil {
return err
}
if p.ExpectedAudience == aud.Audience {
return nil
}
return errors.New("invalid audience")
}
// TokenIDValidationProvider can be used to blacklist some tokens.
// It should be initialized with a slice of forbidden token IDs and will return an error when one of those IDs in encountered.
type TokenIDValidationProvider struct {
ForbiddenTokenIDs []string
}
// Validate will be called during validation of a token
func (p TokenIDValidationProvider) Validate(c []byte) error {
var jti struct {
TokenID string `json:"jti"`
}
if err := json.Unmarshal(c, &jti); err != nil {
return err
}
for _, id := range p.ForbiddenTokenIDs {
if jti.TokenID == id {
return errors.New("token ID is on blacklist")
}
}
return nil
}