|  | package jwt | 
|  |  | 
|  | import ( | 
|  | "time" | 
|  |  | 
|  | "github.com/SermoDigital/jose/crypto" | 
|  | ) | 
|  |  | 
|  | // JWT represents a JWT per RFC 7519. | 
|  | // It's described as an interface instead of a physical structure | 
|  | // because both JWS and JWEs can be JWTs. So, in order to use either, | 
|  | // import one of those two packages and use their "NewJWT" (and other) | 
|  | // functions. | 
|  | type JWT interface { | 
|  | // Claims returns the set of Claims. | 
|  | Claims() Claims | 
|  |  | 
|  | // Validate returns an error describing any issues found while | 
|  | // validating the JWT. For info on the fn parameter, see the | 
|  | // comment on ValidateFunc. | 
|  | Validate(key interface{}, method crypto.SigningMethod, v ...*Validator) error | 
|  |  | 
|  | // Serialize serializes the JWT into its on-the-wire | 
|  | // representation. | 
|  | Serialize(key interface{}) ([]byte, error) | 
|  | } | 
|  |  | 
|  | // ValidateFunc is a function that provides access to the JWT | 
|  | // and allows for custom validation. Keep in mind that the Verify | 
|  | // methods in the JWS/JWE sibling packages call ValidateFunc *after* | 
|  | // validating the JWS/JWE, but *before* any validation per the JWT | 
|  | // RFC. Therefore, the ValidateFunc can be used to short-circuit | 
|  | // verification, but cannot be used to circumvent the RFC. | 
|  | // Custom JWT implementations are free to abuse this, but it is | 
|  | // not recommended. | 
|  | type ValidateFunc func(Claims) error | 
|  |  | 
|  | // Validator represents some of the validation options. | 
|  | type Validator struct { | 
|  | Expected Claims        // If non-nil, these are required to match. | 
|  | EXP      time.Duration // EXPLeeway | 
|  | NBF      time.Duration // NBFLeeway | 
|  | Fn       ValidateFunc  // See ValidateFunc for more information. | 
|  |  | 
|  | _ struct{} // Require explicitly-named struct fields. | 
|  | } | 
|  |  | 
|  | // Validate validates the JWT based on the expected claims in v. | 
|  | // Note: it only validates the registered claims per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1 | 
|  | // | 
|  | // Custom claims should be validated using v's Fn member. | 
|  | func (v *Validator) Validate(j JWT) error { | 
|  | if iss, ok := v.Expected.Issuer(); ok && | 
|  | j.Claims().Get("iss") != iss { | 
|  | return ErrInvalidISSClaim | 
|  | } | 
|  | if sub, ok := v.Expected.Subject(); ok && | 
|  | j.Claims().Get("sub") != sub { | 
|  | return ErrInvalidSUBClaim | 
|  | } | 
|  | if iat, ok := v.Expected.IssuedAt(); ok { | 
|  | if t, ok := j.Claims().GetTime("iat"); !t.Equal(iat) || !ok { | 
|  | return ErrInvalidIATClaim | 
|  | } | 
|  | } | 
|  | if jti, ok := v.Expected.JWTID(); ok && | 
|  | j.Claims().Get("jti") != jti { | 
|  | return ErrInvalidJTIClaim | 
|  | } | 
|  |  | 
|  | if aud, ok := v.Expected.Audience(); ok { | 
|  | aud2, ok := j.Claims().Audience() | 
|  | if !ok || !ValidAudience(aud, aud2) { | 
|  | return ErrInvalidAUDClaim | 
|  | } | 
|  | } | 
|  |  | 
|  | if v.Fn != nil { | 
|  | return v.Fn(j.Claims()) | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | // SetClaim sets the claim with the given val. | 
|  | func (v *Validator) SetClaim(claim string, val interface{}) { | 
|  | v.expect() | 
|  | v.Expected.Set(claim, val) | 
|  | } | 
|  |  | 
|  | // SetIssuer sets the "iss" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.1 | 
|  | func (v *Validator) SetIssuer(iss string) { | 
|  | v.expect() | 
|  | v.Expected.Set("iss", iss) | 
|  | } | 
|  |  | 
|  | // SetSubject sets the "sub" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.2 | 
|  | func (v *Validator) SetSubject(sub string) { | 
|  | v.expect() | 
|  | v.Expected.Set("sub", sub) | 
|  | } | 
|  |  | 
|  | // SetAudience sets the "aud" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.3 | 
|  | func (v *Validator) SetAudience(aud string) { | 
|  | v.expect() | 
|  | v.Expected.Set("aud", aud) | 
|  | } | 
|  |  | 
|  | // SetExpiration sets the "exp" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.4 | 
|  | func (v *Validator) SetExpiration(exp time.Time) { | 
|  | v.expect() | 
|  | v.Expected.Set("exp", exp) | 
|  | } | 
|  |  | 
|  | // SetNotBefore sets the "nbf" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.5 | 
|  | func (v *Validator) SetNotBefore(nbf time.Time) { | 
|  | v.expect() | 
|  | v.Expected.Set("nbf", nbf) | 
|  | } | 
|  |  | 
|  | // SetIssuedAt sets the "iat" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.6 | 
|  | func (v *Validator) SetIssuedAt(iat time.Time) { | 
|  | v.expect() | 
|  | v.Expected.Set("iat", iat) | 
|  | } | 
|  |  | 
|  | // SetJWTID sets the "jti" claim per | 
|  | // https://tools.ietf.org/html/rfc7519#section-4.1.7 | 
|  | func (v *Validator) SetJWTID(jti string) { | 
|  | v.expect() | 
|  | v.Expected.Set("jti", jti) | 
|  | } | 
|  |  | 
|  | func (v *Validator) expect() { | 
|  | if v.Expected == nil { | 
|  | v.Expected = make(Claims) | 
|  | } | 
|  | } |