parser_option.go raw

   1  package jwt
   2  
   3  import "time"
   4  
   5  // ParserOption is used to implement functional-style options that modify the
   6  // behavior of the parser. To add new options, just create a function (ideally
   7  // beginning with With or Without) that returns an anonymous function that takes
   8  // a *Parser type as input and manipulates its configuration accordingly.
   9  type ParserOption func(*Parser)
  10  
  11  // WithValidMethods is an option to supply algorithm methods that the parser
  12  // will check. Only those methods will be considered valid. It is heavily
  13  // encouraged to use this option in order to prevent attacks such as
  14  // https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/.
  15  func WithValidMethods(methods []string) ParserOption {
  16  	return func(p *Parser) {
  17  		p.validMethods = methods
  18  	}
  19  }
  20  
  21  // WithJSONNumber is an option to configure the underlying JSON parser with
  22  // UseNumber.
  23  func WithJSONNumber() ParserOption {
  24  	return func(p *Parser) {
  25  		p.useJSONNumber = true
  26  	}
  27  }
  28  
  29  // WithoutClaimsValidation is an option to disable claims validation. This
  30  // option should only be used if you exactly know what you are doing.
  31  func WithoutClaimsValidation() ParserOption {
  32  	return func(p *Parser) {
  33  		p.skipClaimsValidation = true
  34  	}
  35  }
  36  
  37  // WithLeeway returns the ParserOption for specifying the leeway window.
  38  func WithLeeway(leeway time.Duration) ParserOption {
  39  	return func(p *Parser) {
  40  		p.validator.leeway = leeway
  41  	}
  42  }
  43  
  44  // WithTimeFunc returns the ParserOption for specifying the time func. The
  45  // primary use-case for this is testing. If you are looking for a way to account
  46  // for clock-skew, WithLeeway should be used instead.
  47  func WithTimeFunc(f func() time.Time) ParserOption {
  48  	return func(p *Parser) {
  49  		p.validator.timeFunc = f
  50  	}
  51  }
  52  
  53  // WithIssuedAt returns the ParserOption to enable verification
  54  // of issued-at.
  55  func WithIssuedAt() ParserOption {
  56  	return func(p *Parser) {
  57  		p.validator.verifyIat = true
  58  	}
  59  }
  60  
  61  // WithExpirationRequired returns the ParserOption to make exp claim required.
  62  // By default exp claim is optional.
  63  func WithExpirationRequired() ParserOption {
  64  	return func(p *Parser) {
  65  		p.validator.requireExp = true
  66  	}
  67  }
  68  
  69  // WithAudience configures the validator to require any of the specified
  70  // audiences in the `aud` claim. Validation will fail if the audience is not
  71  // listed in the token or the `aud` claim is missing.
  72  //
  73  // NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
  74  // application-specific. Since this validation API is helping developers in
  75  // writing secure application, we decided to REQUIRE the existence of the claim,
  76  // if an audience is expected.
  77  func WithAudience(aud ...string) ParserOption {
  78  	return func(p *Parser) {
  79  		p.validator.expectedAud = aud
  80  	}
  81  }
  82  
  83  // WithAllAudiences configures the validator to require all the specified
  84  // audiences in the `aud` claim. Validation will fail if the specified audiences
  85  // are not listed in the token or the `aud` claim is missing. Duplicates within
  86  // the list are de-duplicated since internally, we use a map to look up the
  87  // audiences.
  88  //
  89  // NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
  90  // application-specific. Since this validation API is helping developers in
  91  // writing secure application, we decided to REQUIRE the existence of the claim,
  92  // if an audience is expected.
  93  func WithAllAudiences(aud ...string) ParserOption {
  94  	return func(p *Parser) {
  95  		p.validator.expectedAud = aud
  96  		p.validator.expectAllAud = true
  97  	}
  98  }
  99  
 100  // WithIssuer configures the validator to require the specified issuer in the
 101  // `iss` claim. Validation will fail if a different issuer is specified in the
 102  // token or the `iss` claim is missing.
 103  //
 104  // NOTE: While the `iss` claim is OPTIONAL in a JWT, the handling of it is
 105  // application-specific. Since this validation API is helping developers in
 106  // writing secure application, we decided to REQUIRE the existence of the claim,
 107  // if an issuer is expected.
 108  func WithIssuer(iss string) ParserOption {
 109  	return func(p *Parser) {
 110  		p.validator.expectedIss = iss
 111  	}
 112  }
 113  
 114  // WithSubject configures the validator to require the specified subject in the
 115  // `sub` claim. Validation will fail if a different subject is specified in the
 116  // token or the `sub` claim is missing.
 117  //
 118  // NOTE: While the `sub` claim is OPTIONAL in a JWT, the handling of it is
 119  // application-specific. Since this validation API is helping developers in
 120  // writing secure application, we decided to REQUIRE the existence of the claim,
 121  // if a subject is expected.
 122  func WithSubject(sub string) ParserOption {
 123  	return func(p *Parser) {
 124  		p.validator.expectedSub = sub
 125  	}
 126  }
 127  
 128  // WithPaddingAllowed will enable the codec used for decoding JWTs to allow
 129  // padding. Note that the JWS RFC7515 states that the tokens will utilize a
 130  // Base64url encoding with no padding. Unfortunately, some implementations of
 131  // JWT are producing non-standard tokens, and thus require support for decoding.
 132  func WithPaddingAllowed() ParserOption {
 133  	return func(p *Parser) {
 134  		p.decodePaddingAllowed = true
 135  	}
 136  }
 137  
 138  // WithStrictDecoding will switch the codec used for decoding JWTs into strict
 139  // mode. In this mode, the decoder requires that trailing padding bits are zero,
 140  // as described in RFC 4648 section 3.5.
 141  func WithStrictDecoding() ParserOption {
 142  	return func(p *Parser) {
 143  		p.decodeStrict = true
 144  	}
 145  }
 146