mirror of https://github.com/golang-jwt/jwt.git
Adds go module support /v4 (#41)
Additionally, added `staticcheck` for basic static code analysis (#44) Co-authored-by: Christian Banse <oxisto@aybaze.com>
This commit is contained in:
parent
4bbdd8ac62
commit
2ebb50f957
|
@ -8,6 +8,18 @@ on:
|
|||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- uses: reviewdog/action-staticcheck@v1
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
reporter: github-pr-review
|
||||
filter_mode: nofilter
|
||||
fail_on_error: true
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
|
@ -17,8 +29,6 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: src/github.com/golang-jwt/jwt
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
|
@ -28,6 +38,3 @@ jobs:
|
|||
go vet ./...
|
||||
go test -v ./...
|
||||
go build ./...
|
||||
env:
|
||||
GO111MODULE: auto
|
||||
GOPATH: ${{ github.workspace }}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
## Migration Guide (v3.2.1)
|
||||
## Migration Guide (v4.0.0)
|
||||
|
||||
Starting from [v3.2.1](https://github.com/golang-jwt/jwt/releases/tag/v3.2.1]), the import path has changed from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt`. Future releases will be using the `github.com/golang-jwt/jwt` import path and continue the existing versioning scheme of `v3.x.x+incompatible`. Backwards-compatible patches and fixes will be done on the `v3` release branch, where as new build-breaking features will be developed in a `v4` release, possibly including a SIV-style import path.
|
||||
Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0]), the import path will be:
|
||||
|
||||
### go.mod replacement
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
|
||||
In a first step, the easiest way is to use `go mod edit` to issue a replacement.
|
||||
The `/v4` version will be backwards compatible with existing `v3.x.y` tags in this repo, as well as
|
||||
`github.com/dgrijalva/jwt-go`. For most users this should be a drop-in replacement, if you're having
|
||||
troubles migrating, please open an issue.
|
||||
|
||||
You can replace all occurrences of `github.com/dgrijalva/jwt-go` or `github.com/golang-jwt/jwt` with `github.com/golang-jwt/jwt/v4`, either manually or by using tools such as `sed` or `gofmt`.
|
||||
|
||||
And then you'd typically run:
|
||||
|
||||
```
|
||||
go mod edit -replace github.com/dgrijalva/jwt-go=github.com/golang-jwt/jwt@v3.2.1+incompatible
|
||||
go get github.com/golang-jwt/jwt/v4
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
This will still keep the old import path in your code but replace it with the new package and also introduce a new indirect dependency to `github.com/golang-jwt/jwt`. Try to compile your project; it should still work.
|
||||
|
||||
### Cleanup
|
||||
|
||||
If your code still consistently builds, you can replace all occurences of `github.com/dgrijalva/jwt-go` with `github.com/golang-jwt/jwt`, either manually or by using tools such as `sed`. Finally, the `replace` directive in the `go.mod` file can be removed.
|
||||
|
||||
## Older releases (before v3.2.0)
|
||||
|
||||
The original migration guide for older releases can be found at https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md.
|
10
README.md
10
README.md
|
@ -5,9 +5,11 @@
|
|||
|
||||
A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](https://datatracker.ietf.org/doc/html/rfc7519).
|
||||
|
||||
**IMPORT PATH CHANGE:** Starting from [v3.2.1](https://github.com/golang-jwt/jwt/releases/tag/v3.2.1), the import path has changed from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt`. After the original author of the library suggested migrating the maintenance of `jwt-go`, a dedicated team of open source maintainers decided to clone the existing library into this repository. See [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a detailed discussion on this topic.
|
||||
Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) this project adds Go module support, but maintains backwards compataibility with older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`.
|
||||
See the `MIGRATION_GUIDE.md` for more information.
|
||||
|
||||
> After the original author of the library suggested migrating the maintenance of `jwt-go`, a dedicated team of open source maintainers decided to clone the existing library into this repository. See [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a detailed discussion on this topic.
|
||||
|
||||
Future releases will be using the `github.com/golang-jwt/jwt` import path and continue the existing versioning scheme of `v3.x.x+incompatible`. Backwards-compatible patches and fixes will be done on the `v3` release branch, where as new build-breaking features will be developed in a `v4` release, possibly including a SIV-style import path.
|
||||
|
||||
**SECURITY NOTICE:** Some older versions of Go have a security issue in the crypto/elliptic. Recommendation is to upgrade to at least 1.15 See issue [dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more detail.
|
||||
|
||||
|
@ -60,10 +62,8 @@ This library is considered production ready. Feedback and feature requests are
|
|||
|
||||
This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `main`. Periodically, versions will be tagged from `main`. You can find all the releases on [the project releases page](https://github.com/golang-jwt/jwt/releases).
|
||||
|
||||
While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/golang-jwt/jwt.v3`. It will do the right thing WRT semantic versioning.
|
||||
|
||||
**BREAKING CHANGES:***
|
||||
* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code.
|
||||
A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code.
|
||||
|
||||
## Usage Tips
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
## `jwt-go` Version History
|
||||
|
||||
#### 4.0.0
|
||||
|
||||
* Introduces support for Go modules. The `v4` version will be backwards compatible with `v3.x.y`.
|
||||
|
||||
#### 3.2.2
|
||||
|
||||
* Starting from this release, we are adopting the policy to support the most 2 recent versions of Go currently available. By the time of this release, this is Go 1.15 and 1.16 ([#28](https://github.com/golang-jwt/jwt/pull/28)).
|
||||
|
|
17
claims.go
17
claims.go
|
@ -6,13 +6,13 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// For a type to be a Claims object, it must just have a Valid method that determines
|
||||
// Claims must just have a Valid method that determines
|
||||
// if the token is invalid for any supported reason
|
||||
type Claims interface {
|
||||
Valid() error
|
||||
}
|
||||
|
||||
// Structured version of Claims Section, as referenced at
|
||||
// StandardClaims are a structured version of the Claims Section, as referenced at
|
||||
// https://tools.ietf.org/html/rfc7519#section-4.1
|
||||
// See examples for how to use this with your own claim types
|
||||
type StandardClaims struct {
|
||||
|
@ -25,8 +25,7 @@ type StandardClaims struct {
|
|||
Subject string `json:"sub,omitempty"`
|
||||
}
|
||||
|
||||
// Validates time based claims "exp, iat, nbf".
|
||||
// There is no accounting for clock skew.
|
||||
// Valid validates time based claims "exp, iat, nbf". There is no accounting for clock skew.
|
||||
// As well, if any of the above claims are not in the token, it will still
|
||||
// be considered a valid claim.
|
||||
func (c StandardClaims) Valid() error {
|
||||
|
@ -58,31 +57,31 @@ func (c StandardClaims) Valid() error {
|
|||
return vErr
|
||||
}
|
||||
|
||||
// Compares the aud claim against cmp.
|
||||
// VerifyAudience compares the aud claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
|
||||
return verifyAud([]string{c.Audience}, cmp, req)
|
||||
}
|
||||
|
||||
// Compares the exp claim against cmp.
|
||||
// VerifyExpiresAt compares the exp claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
|
||||
return verifyExp(c.ExpiresAt, cmp, req)
|
||||
}
|
||||
|
||||
// Compares the iat claim against cmp.
|
||||
// VerifyIssuedAt compares the iat claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
|
||||
return verifyIat(c.IssuedAt, cmp, req)
|
||||
}
|
||||
|
||||
// Compares the iss claim against cmp.
|
||||
// VerifyIssuer compares the iss claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
|
||||
return verifyIss(c.Issuer, cmp, req)
|
||||
}
|
||||
|
||||
// Compares the nbf claim against cmp.
|
||||
// VerifyNotBefore compares the nbf claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
|
||||
return verifyNbf(c.NotBefore, cmp, req)
|
||||
|
|
|
@ -16,5 +16,4 @@ To simply display a token, use:
|
|||
|
||||
You can install this tool with the following command:
|
||||
|
||||
go install github.com/golang-jwt/jwt/cmd/jwt
|
||||
|
||||
go install github.com/golang-jwt/jwt/v4/cmd/jwt
|
|
@ -1,23 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ArgList map[string]string
|
||||
|
||||
func (l ArgList) String() string {
|
||||
data, _ := json.Marshal(l)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func (l ArgList) Set(arg string) error {
|
||||
parts := strings.SplitN(arg, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("Invalid argument '%v'. Must use format 'key=value'. %v", arg, parts)
|
||||
}
|
||||
l[parts[0]] = parts[1]
|
||||
return nil
|
||||
}
|
|
@ -16,7 +16,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -67,14 +67,14 @@ func start() error {
|
|||
return showToken()
|
||||
} else {
|
||||
flag.Usage()
|
||||
return fmt.Errorf("None of the required flags are present. What do you want me to do?")
|
||||
return fmt.Errorf("none of the required flags are present. What do you want me to do?")
|
||||
}
|
||||
}
|
||||
|
||||
// Helper func: Read input from specified file or stdin
|
||||
func loadData(p string) ([]byte, error) {
|
||||
if p == "" {
|
||||
return nil, fmt.Errorf("No path specified")
|
||||
return nil, fmt.Errorf("no path specified")
|
||||
}
|
||||
|
||||
var rdr io.Reader
|
||||
|
@ -117,7 +117,7 @@ func verifyToken() error {
|
|||
// get the token
|
||||
tokData, err := loadData(*flagVerify)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read token: %v", err)
|
||||
return fmt.Errorf("couldn't read token: %w", err)
|
||||
}
|
||||
|
||||
// trim possible whitespace from token
|
||||
|
@ -150,17 +150,17 @@ func verifyToken() error {
|
|||
|
||||
// Print an error if we can't parse for some reason
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't parse token: %v", err)
|
||||
return fmt.Errorf("couldn't parse token: %w", err)
|
||||
}
|
||||
|
||||
// Is token invalid?
|
||||
if !token.Valid {
|
||||
return fmt.Errorf("Token is invalid")
|
||||
return fmt.Errorf("token is invalid")
|
||||
}
|
||||
|
||||
// Print the token details
|
||||
if err := printJSON(token.Claims); err != nil {
|
||||
return fmt.Errorf("Failed to output claims: %v", err)
|
||||
return fmt.Errorf("failed to output claims: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -172,7 +172,7 @@ func signToken() error {
|
|||
// get the token data from command line arguments
|
||||
tokData, err := loadData(*flagSign)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read token: %v", err)
|
||||
return fmt.Errorf("couldn't read token: %w", err)
|
||||
} else if *flagDebug {
|
||||
fmt.Fprintf(os.Stderr, "Token: %v bytes", len(tokData))
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ func signToken() error {
|
|||
// parse the JSON of the claims
|
||||
var claims jwt.MapClaims
|
||||
if err := json.Unmarshal(tokData, &claims); err != nil {
|
||||
return fmt.Errorf("Couldn't parse claims JSON: %v", err)
|
||||
return fmt.Errorf("couldn't parse claims JSON: %w", err)
|
||||
}
|
||||
|
||||
// add command line claims
|
||||
|
@ -194,13 +194,13 @@ func signToken() error {
|
|||
var key interface{}
|
||||
key, err = loadData(*flagKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read key: %v", err)
|
||||
return fmt.Errorf("couldn't read key: %w", err)
|
||||
}
|
||||
|
||||
// get the signing alg
|
||||
alg := jwt.GetSigningMethod(*flagAlg)
|
||||
if alg == nil {
|
||||
return fmt.Errorf("Couldn't find signing method: %v", *flagAlg)
|
||||
return fmt.Errorf("couldn't find signing method: %v", *flagAlg)
|
||||
}
|
||||
|
||||
// create a new token
|
||||
|
@ -215,7 +215,7 @@ func signToken() error {
|
|||
|
||||
if isEs() {
|
||||
if k, ok := key.([]byte); !ok {
|
||||
return fmt.Errorf("Couldn't convert key data to key")
|
||||
return fmt.Errorf("couldn't convert key data to key")
|
||||
} else {
|
||||
key, err = jwt.ParseECPrivateKeyFromPEM(k)
|
||||
if err != nil {
|
||||
|
@ -224,7 +224,7 @@ func signToken() error {
|
|||
}
|
||||
} else if isRs() {
|
||||
if k, ok := key.([]byte); !ok {
|
||||
return fmt.Errorf("Couldn't convert key data to key")
|
||||
return fmt.Errorf("couldn't convert key data to key")
|
||||
} else {
|
||||
key, err = jwt.ParseRSAPrivateKeyFromPEM(k)
|
||||
if err != nil {
|
||||
|
@ -233,7 +233,7 @@ func signToken() error {
|
|||
}
|
||||
} else if isEd() {
|
||||
if k, ok := key.([]byte); !ok {
|
||||
return fmt.Errorf("Couldn't convert key data to key")
|
||||
return fmt.Errorf("couldn't convert key data to key")
|
||||
} else {
|
||||
key, err = jwt.ParseEdPrivateKeyFromPEM(k)
|
||||
if err != nil {
|
||||
|
@ -245,7 +245,7 @@ func signToken() error {
|
|||
if out, err := token.SignedString(key); err == nil {
|
||||
fmt.Println(out)
|
||||
} else {
|
||||
return fmt.Errorf("Error signing token: %v", err)
|
||||
return fmt.Errorf("error signing token: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -256,7 +256,7 @@ func showToken() error {
|
|||
// get the token
|
||||
tokData, err := loadData(*flagShow)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read token: %v", err)
|
||||
return fmt.Errorf("couldn't read token: %w", err)
|
||||
}
|
||||
|
||||
// trim possible whitespace from token
|
||||
|
@ -267,18 +267,18 @@ func showToken() error {
|
|||
|
||||
token, err := jwt.Parse(string(tokData), nil)
|
||||
if token == nil {
|
||||
return fmt.Errorf("malformed token: %v", err)
|
||||
return fmt.Errorf("malformed token: %w", err)
|
||||
}
|
||||
|
||||
// Print the token details
|
||||
fmt.Println("Header:")
|
||||
if err := printJSON(token.Header); err != nil {
|
||||
return fmt.Errorf("Failed to output header: %v", err)
|
||||
return fmt.Errorf("failed to output header: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Claims:")
|
||||
if err := printJSON(token.Claims); err != nil {
|
||||
return fmt.Errorf("Failed to output claims: %v", err)
|
||||
return fmt.Errorf("failed to output claims: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -295,3 +295,19 @@ func isRs() bool {
|
|||
func isEd() bool {
|
||||
return strings.HasPrefix(strings.ToUpper(*flagAlg), "Ed")
|
||||
}
|
||||
|
||||
type ArgList map[string]string
|
||||
|
||||
func (l ArgList) String() string {
|
||||
data, _ := json.Marshal(l)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func (l ArgList) Set(arg string) error {
|
||||
parts := strings.SplitN(arg, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("invalid argument '%v'. Must use format 'key=value'. %v", arg, parts)
|
||||
}
|
||||
l[parts[0]] = parts[1]
|
||||
return nil
|
||||
}
|
6
ecdsa.go
6
ecdsa.go
|
@ -13,7 +13,7 @@ var (
|
|||
ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
|
||||
)
|
||||
|
||||
// Implements the ECDSA family of signing methods signing methods
|
||||
// SigningMethodECDSA implements the ECDSA family of signing methods.
|
||||
// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
|
||||
type SigningMethodECDSA struct {
|
||||
Name string
|
||||
|
@ -53,7 +53,7 @@ func (m *SigningMethodECDSA) Alg() string {
|
|||
return m.Name
|
||||
}
|
||||
|
||||
// Implements the Verify method from SigningMethod
|
||||
// Verify implements token verification for the SigningMethod.
|
||||
// For this verify method, key must be an ecdsa.PublicKey struct
|
||||
func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
|
||||
var err error
|
||||
|
@ -95,7 +95,7 @@ func (m *SigningMethodECDSA) Verify(signingString, signature string, key interfa
|
|||
return ErrECDSAVerification
|
||||
}
|
||||
|
||||
// Implements the Sign method from SigningMethod
|
||||
// Sign implements token signing for the SigningMethod.
|
||||
// For this signing method, key must be an ecdsa.PrivateKey struct
|
||||
func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
|
||||
// Get the key
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var ecdsaTestData = []struct {
|
||||
|
|
|
@ -8,11 +8,11 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrNotECPublicKey = errors.New("Key is not a valid ECDSA public key")
|
||||
ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key")
|
||||
ErrNotECPublicKey = errors.New("key is not a valid ECDSA public key")
|
||||
ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key")
|
||||
)
|
||||
|
||||
// Parse PEM encoded Elliptic Curve Private Key Structure
|
||||
// ParseECPrivateKeyFromPEM parses a PEM encoded Elliptic Curve Private Key Structure
|
||||
func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
|
||||
var err error
|
||||
|
||||
|
@ -39,7 +39,7 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
|
|||
return pkey, nil
|
||||
}
|
||||
|
||||
// Parse PEM encoded PKCS1 or PKCS8 public key
|
||||
// ParseECPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key
|
||||
func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
|
||||
var err error
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ var (
|
|||
ErrEd25519Verification = errors.New("ed25519: verification error")
|
||||
)
|
||||
|
||||
// Implements the EdDSA family
|
||||
// SigningMethodEd25519 implements the EdDSA family.
|
||||
// Expects ed25519.PrivateKey for signing and ed25519.PublicKey for verification
|
||||
type SigningMethodEd25519 struct{}
|
||||
|
||||
|
@ -30,7 +30,7 @@ func (m *SigningMethodEd25519) Alg() string {
|
|||
return "EdDSA"
|
||||
}
|
||||
|
||||
// Implements the Verify method from SigningMethod
|
||||
// Verify implements token verification for the SigningMethod.
|
||||
// For this verify method, key must be an ed25519.PublicKey
|
||||
func (m *SigningMethodEd25519) Verify(signingString, signature string, key interface{}) error {
|
||||
var err error
|
||||
|
@ -59,7 +59,7 @@ func (m *SigningMethodEd25519) Verify(signingString, signature string, key inter
|
|||
return nil
|
||||
}
|
||||
|
||||
// Implements the Sign method from SigningMethod
|
||||
// Sign implements token signing for the SigningMethod.
|
||||
// For this signing method, key must be an ed25519.PrivateKey
|
||||
func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) (string, error) {
|
||||
var ed25519Key ed25519.PrivateKey
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var ed25519TestData = []struct {
|
||||
|
|
|
@ -9,11 +9,11 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrNotEdPrivateKey = errors.New("Key is not a valid Ed25519 private key")
|
||||
ErrNotEdPublicKey = errors.New("Key is not a valid Ed25519 public key")
|
||||
ErrNotEdPrivateKey = errors.New("key is not a valid Ed25519 private key")
|
||||
ErrNotEdPublicKey = errors.New("key is not a valid Ed25519 public key")
|
||||
)
|
||||
|
||||
// Parse PEM-encoded Edwards curve private key
|
||||
// ParseEdPrivateKeyFromPEM parses a PEM-encoded Edwards curve private key
|
||||
func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) {
|
||||
var err error
|
||||
|
||||
|
@ -38,7 +38,7 @@ func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) {
|
|||
return pkey, nil
|
||||
}
|
||||
|
||||
// Parse PEM-encoded Edwards curve public key
|
||||
// ParseEdPublicKeyFromPEM parses a PEM-encoded Edwards curve public key
|
||||
func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) {
|
||||
var err error
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ const (
|
|||
ValidationErrorClaimsInvalid // Generic claims validation error
|
||||
)
|
||||
|
||||
// Helper for constructing a ValidationError with a string error message
|
||||
// NewValidationError is a helper for constructing a ValidationError with a string error message
|
||||
func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
|
||||
return &ValidationError{
|
||||
text: errorText,
|
||||
|
@ -35,14 +35,14 @@ func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
|
|||
}
|
||||
}
|
||||
|
||||
// The error from Parse if token is not valid
|
||||
// ValidationError represents an error from Parse if token is not valid
|
||||
type ValidationError struct {
|
||||
Inner error // stores the error returned by external dependencies, i.e.: KeyFunc
|
||||
Errors uint32 // bitfield. see ValidationError... constants
|
||||
text string // errors that do not have a valid error just have text
|
||||
}
|
||||
|
||||
// Validation error is an error type
|
||||
// Error is the implementation of the err interface.
|
||||
func (e ValidationError) Error() string {
|
||||
if e.Inner != nil {
|
||||
return e.Inner.Error()
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
// Example (atypical) using the StandardClaims type by itself to parse a token.
|
||||
|
|
6
hmac.go
6
hmac.go
|
@ -6,7 +6,7 @@ import (
|
|||
"errors"
|
||||
)
|
||||
|
||||
// Implements the HMAC-SHA family of signing methods signing methods
|
||||
// SigningMethodHMAC implements the HMAC-SHA family of signing methods.
|
||||
// Expects key type of []byte for both signing and validation
|
||||
type SigningMethodHMAC struct {
|
||||
Name string
|
||||
|
@ -45,7 +45,7 @@ func (m *SigningMethodHMAC) Alg() string {
|
|||
return m.Name
|
||||
}
|
||||
|
||||
// Verify the signature of HSXXX tokens. Returns nil if the signature is valid.
|
||||
// Verify implements token verification for the SigningMethod. Returns nil if the signature is valid.
|
||||
func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {
|
||||
// Verify the key is the right type
|
||||
keyBytes, ok := key.([]byte)
|
||||
|
@ -77,7 +77,7 @@ func (m *SigningMethodHMAC) Verify(signingString, signature string, key interfac
|
|||
return nil
|
||||
}
|
||||
|
||||
// Implements the Sign method from SigningMethod for this signing method.
|
||||
// Sign implements token signing for the SigningMethod.
|
||||
// Key must be []byte
|
||||
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
|
||||
if keyBytes, ok := key.([]byte); ok {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
// For HMAC signing method, the key can be any []byte. It is recommended to generate
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var hmacTestData = []struct {
|
||||
|
|
|
@ -16,8 +16,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/request"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4/request"
|
||||
)
|
||||
|
||||
// location of the files used for signing and verification
|
||||
|
@ -30,11 +30,6 @@ var (
|
|||
verifyKey *rsa.PublicKey
|
||||
signKey *rsa.PrivateKey
|
||||
serverPort int
|
||||
// storing sample username/password pairs
|
||||
// don't do this on a real server
|
||||
users = map[string]string{
|
||||
"test": "known",
|
||||
}
|
||||
)
|
||||
|
||||
// read the key files before starting http handlers
|
||||
|
@ -65,8 +60,6 @@ func init() {
|
|||
}()
|
||||
}
|
||||
|
||||
var start func()
|
||||
|
||||
func fatal(err error) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -199,11 +192,11 @@ func authHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// only accessible with a valid token
|
||||
func restrictedHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Get token from request
|
||||
token, err := request.ParseFromRequestWithClaims(r, request.OAuth2Extractor, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
|
||||
token, err := request.ParseFromRequest(r, request.OAuth2Extractor, func(token *jwt.Token) (interface{}, error) {
|
||||
// since we only use the one private key to sign the tokens,
|
||||
// we also only use its public counter part to verify
|
||||
return verifyKey, nil
|
||||
})
|
||||
}, request.WithClaims(&CustomClaimsExample{}))
|
||||
|
||||
// If the token is missing or invalid, return error
|
||||
if err != nil {
|
||||
|
@ -214,5 +207,4 @@ func restrictedHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Token is valid
|
||||
fmt.Fprintln(w, "Welcome,", token.Claims.(*CustomClaimsExample).Name)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
// "fmt"
|
||||
)
|
||||
|
||||
// Claims type that uses the map[string]interface{} for JSON decoding
|
||||
// MapClaims is a claims type that uses the map[string]interface{} for JSON decoding.
|
||||
// This is the default claims type if you don't supply one
|
||||
type MapClaims map[string]interface{}
|
||||
|
||||
|
@ -31,7 +31,7 @@ func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
|
|||
return verifyAud(aud, cmp, req)
|
||||
}
|
||||
|
||||
// Compares the exp claim against cmp.
|
||||
// VerifyExpiresAt compares the exp claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
|
||||
exp, ok := m["exp"]
|
||||
|
@ -48,7 +48,7 @@ func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Compares the iat claim against cmp.
|
||||
// VerifyIssuedAt compares the iat claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
|
||||
iat, ok := m["iat"]
|
||||
|
@ -65,14 +65,14 @@ func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Compares the iss claim against cmp.
|
||||
// VerifyIssuer compares the iss claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
|
||||
iss, _ := m["iss"].(string)
|
||||
return verifyIss(iss, cmp, req)
|
||||
}
|
||||
|
||||
// Compares the nbf claim against cmp.
|
||||
// VerifyNotBefore compares the nbf claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
|
||||
nbf, ok := m["nbf"]
|
||||
|
@ -89,7 +89,7 @@ func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Validates time based claims "exp, iat, nbf".
|
||||
// Valid calidates time based claims "exp, iat, nbf".
|
||||
// There is no accounting for clock skew.
|
||||
// As well, if any of the above claims are not in the token, it will still
|
||||
// be considered a valid claim.
|
||||
|
|
2
none.go
2
none.go
|
@ -1,6 +1,6 @@
|
|||
package jwt
|
||||
|
||||
// Implements the none signing method. This is required by the spec
|
||||
// SigningMethodNone implements the none signing method. This is required by the spec
|
||||
// but you probably should never use it.
|
||||
var SigningMethodNone *signingMethodNone
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var noneTestData = []struct {
|
||||
|
|
12
parser.go
12
parser.go
|
@ -13,7 +13,7 @@ type Parser struct {
|
|||
SkipClaimsValidation bool // Skip claims validation during token parsing
|
||||
}
|
||||
|
||||
// Parse, validate, and return a token.
|
||||
// Parse parses, validates, and returns a token.
|
||||
// keyFunc will receive the parsed token and should return the key for validating.
|
||||
// If everything is kosher, err will be nil
|
||||
func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
|
||||
|
@ -87,12 +87,12 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
|
|||
return token, vErr
|
||||
}
|
||||
|
||||
// WARNING: Don't use this method unless you know what you're doing
|
||||
// ParseUnverified parses the token but doesn't validate the signature.
|
||||
//
|
||||
// This method parses the token but doesn't validate the signature. It's only
|
||||
// ever useful in cases where you know the signature is valid (because it has
|
||||
// been checked previously in the stack) and you want to extract values from
|
||||
// it.
|
||||
// WARNING: Don't use this method unless you know what you're doing.
|
||||
//
|
||||
// It's only ever useful in cases where you know the signature is valid (because it has
|
||||
// been checked previously in the stack) and you want to extract values from it.
|
||||
func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
|
||||
parts = strings.Split(tokenString, ".")
|
||||
if len(parts) != 3 {
|
||||
|
|
|
@ -8,17 +8,17 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/test"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4/test"
|
||||
)
|
||||
|
||||
var keyFuncError error = fmt.Errorf("error loading key")
|
||||
var errKeyFuncError error = fmt.Errorf("error loading key")
|
||||
|
||||
var (
|
||||
jwtTestDefaultKey *rsa.PublicKey
|
||||
defaultKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil }
|
||||
emptyKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil }
|
||||
errorKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, keyFuncError }
|
||||
errorKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, errKeyFuncError }
|
||||
nilKeyFunc jwt.Keyfunc = nil
|
||||
)
|
||||
|
||||
|
@ -236,8 +236,8 @@ func TestParser_Parse(t *testing.T) {
|
|||
t.Errorf("[%v] Errors don't match expectation. %v != %v", data.name, e, data.errors)
|
||||
}
|
||||
|
||||
if err.Error() == keyFuncError.Error() && ve.Inner != keyFuncError {
|
||||
t.Errorf("[%v] Inner error does not match expectation. %v != %v", data.name, ve.Inner, keyFuncError)
|
||||
if err.Error() == errKeyFuncError.Error() && ve.Inner != errKeyFuncError {
|
||||
t.Errorf("[%v] Inner error does not match expectation. %v != %v", data.name, ve.Inner, errKeyFuncError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ var (
|
|||
ErrNoTokenInRequest = errors.New("no token present in request")
|
||||
)
|
||||
|
||||
// Interface for extracting a token from an HTTP request.
|
||||
// Extractor is an interface for extracting a token from an HTTP request.
|
||||
// The ExtractToken method should return a token string or an error.
|
||||
// If no token is present, you must return ErrNoTokenInRequest.
|
||||
type Extractor interface {
|
||||
ExtractToken(*http.Request) (string, error)
|
||||
}
|
||||
|
||||
// Extractor for finding a token in a header. Looks at each specified
|
||||
// header in order until there's a match
|
||||
// HeaderExtractor is an extractor for finding a token in a header.
|
||||
// Looks at each specified header in order until there's a match
|
||||
type HeaderExtractor []string
|
||||
|
||||
func (e HeaderExtractor) ExtractToken(req *http.Request) (string, error) {
|
||||
|
@ -31,7 +31,7 @@ func (e HeaderExtractor) ExtractToken(req *http.Request) (string, error) {
|
|||
return "", ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
// Extract token from request arguments. This includes a POSTed form or
|
||||
// ArgumentExtractor extracts a token from request arguments. This includes a POSTed form or
|
||||
// GET URL arguments. Argument names are tried in order until there's a match.
|
||||
// This extractor calls `ParseMultipartForm` on the request
|
||||
type ArgumentExtractor []string
|
||||
|
@ -50,7 +50,7 @@ func (e ArgumentExtractor) ExtractToken(req *http.Request) (string, error) {
|
|||
return "", ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
// Tries Extractors in order until one returns a token string or an error occurs
|
||||
// MultiExtractor tries Extractors in order until one returns a token string or an error occurs
|
||||
type MultiExtractor []Extractor
|
||||
|
||||
func (e MultiExtractor) ExtractToken(req *http.Request) (string, error) {
|
||||
|
@ -65,7 +65,7 @@ func (e MultiExtractor) ExtractToken(req *http.Request) (string, error) {
|
|||
return "", ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
// Wrap an Extractor in this to post-process the value before it's handed off.
|
||||
// PostExtractionFilter wraps an Extractor in this to post-process the value before it's handed off.
|
||||
// See AuthorizationHeaderExtractor for an example
|
||||
type PostExtractionFilter struct {
|
||||
Extractor
|
||||
|
|
|
@ -13,14 +13,14 @@ func stripBearerPrefixFromTokenString(tok string) (string, error) {
|
|||
return tok, nil
|
||||
}
|
||||
|
||||
// Extract bearer token from Authorization header
|
||||
// AuthorizationHeaderExtractor extracts a bearer token from Authorization header
|
||||
// Uses PostExtractionFilter to strip "Bearer " prefix from header
|
||||
var AuthorizationHeaderExtractor = &PostExtractionFilter{
|
||||
HeaderExtractor{"Authorization"},
|
||||
stripBearerPrefixFromTokenString,
|
||||
}
|
||||
|
||||
// Extractor for OAuth2 access tokens. Looks in 'Authorization'
|
||||
// OAuth2Extractor is an Extractor for OAuth2 access tokens. Looks in 'Authorization'
|
||||
// header then 'access_token' argument for a token.
|
||||
var OAuth2Extractor = &MultiExtractor{
|
||||
AuthorizationHeaderExtractor,
|
||||
|
|
|
@ -3,10 +3,10 @@ package request
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
// Extract and parse a JWT token from an HTTP request.
|
||||
// ParseFromRequest extracts and parses a JWT token from an HTTP request.
|
||||
// This behaves the same as Parse, but accepts a request and an extractor
|
||||
// instead of a token string. The Extractor interface allows you to define
|
||||
// the logic for extracting a token. Several useful implementations are provided.
|
||||
|
@ -39,8 +39,9 @@ func ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfun
|
|||
return p.parser.ParseWithClaims(tokenString, p.claims, keyFunc)
|
||||
}
|
||||
|
||||
// ParseFromRequest but with custom Claims type
|
||||
// DEPRECATED: use ParseFromRequest and the WithClaims option
|
||||
// ParseFromRequestWithClaims is an alias for ParseFromRequest but with custom Claims type.
|
||||
//
|
||||
// Deprecated: use ParseFromRequest and the WithClaims option
|
||||
func ParseFromRequestWithClaims(req *http.Request, extractor Extractor, claims jwt.Claims, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) {
|
||||
return ParseFromRequest(req, extractor, keyFunc, WithClaims(claims))
|
||||
}
|
||||
|
@ -54,14 +55,14 @@ type fromRequestParser struct {
|
|||
|
||||
type ParseFromRequestOption func(*fromRequestParser)
|
||||
|
||||
// Parse with custom claims
|
||||
// WithClaims parses with custom claims
|
||||
func WithClaims(claims jwt.Claims) ParseFromRequestOption {
|
||||
return func(p *fromRequestParser) {
|
||||
p.claims = claims
|
||||
}
|
||||
}
|
||||
|
||||
// Parse using a custom parser
|
||||
// WithParser parses using a custom parser
|
||||
func WithParser(parser *jwt.Parser) ParseFromRequestOption {
|
||||
return func(p *fromRequestParser) {
|
||||
p.parser = parser
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/test"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4/test"
|
||||
)
|
||||
|
||||
var requestTestData = []struct {
|
||||
|
|
6
rsa.go
6
rsa.go
|
@ -6,7 +6,7 @@ import (
|
|||
"crypto/rsa"
|
||||
)
|
||||
|
||||
// Implements the RSA family of signing methods signing methods
|
||||
// SigningMethodRSA implements the RSA family of signing methods.
|
||||
// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
|
||||
type SigningMethodRSA struct {
|
||||
Name string
|
||||
|
@ -44,7 +44,7 @@ func (m *SigningMethodRSA) Alg() string {
|
|||
return m.Name
|
||||
}
|
||||
|
||||
// Implements the Verify method from SigningMethod
|
||||
// Verify implements token verification for the SigningMethod
|
||||
// For this signing method, must be an *rsa.PublicKey structure.
|
||||
func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
|
||||
var err error
|
||||
|
@ -73,7 +73,7 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
|
|||
return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
|
||||
}
|
||||
|
||||
// Implements the Sign method from SigningMethod
|
||||
// Sign implements token signing for the SigningMethod
|
||||
// For this signing method, must be an *rsa.PrivateKey structure.
|
||||
func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {
|
||||
var rsaKey *rsa.PrivateKey
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"crypto/rsa"
|
||||
)
|
||||
|
||||
// Implements the RSAPSS family of signing methods signing methods
|
||||
// SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods
|
||||
type SigningMethodRSAPSS struct {
|
||||
*SigningMethodRSA
|
||||
Options *rsa.PSSOptions
|
||||
|
@ -79,7 +79,7 @@ func init() {
|
|||
})
|
||||
}
|
||||
|
||||
// Implements the Verify method from SigningMethod
|
||||
// Verify implements token verification for the SigningMethod.
|
||||
// For this verify method, key must be an rsa.PublicKey struct
|
||||
func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error {
|
||||
var err error
|
||||
|
@ -113,7 +113,7 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf
|
|||
return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
|
||||
}
|
||||
|
||||
// Implements the Sign method from SigningMethod
|
||||
// Sign implements token signing for the SigningMethod.
|
||||
// For this signing method, key must be an rsa.PrivateKey struct
|
||||
func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) {
|
||||
var rsaKey *rsa.PrivateKey
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/test"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4/test"
|
||||
)
|
||||
|
||||
var rsaPSSTestData = []struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var rsaTestData = []struct {
|
||||
|
|
16
rsa_utils.go
16
rsa_utils.go
|
@ -8,12 +8,12 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be a PEM encoded PKCS1 or PKCS8 key")
|
||||
ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key")
|
||||
ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key")
|
||||
ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be a PEM encoded PKCS1 or PKCS8 key")
|
||||
ErrNotRSAPrivateKey = errors.New("key is not a valid RSA private key")
|
||||
ErrNotRSAPublicKey = errors.New("key is not a valid RSA public key")
|
||||
)
|
||||
|
||||
// Parse PEM encoded PKCS1 or PKCS8 private key
|
||||
// ParseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key
|
||||
func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
|
||||
var err error
|
||||
|
||||
|
@ -39,7 +39,11 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
|
|||
return pkey, nil
|
||||
}
|
||||
|
||||
// Parse PEM encoded PKCS1 or PKCS8 private key protected with password
|
||||
// ParseRSAPrivateKeyFromPEMWithPassword parses a PEM encoded PKCS1 or PKCS8 private key protected with password
|
||||
//
|
||||
// Deprecated: This function is deprecated and should not be used anymore. It uses the deprecated x509.DecryptPEMBlock
|
||||
// function, which was deprecated since RFC 1423 is regarded insecure by design. Unfortunately, there is no alternative
|
||||
// in the Go standard library for now. See https://github.com/golang/go/issues/8860.
|
||||
func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) {
|
||||
var err error
|
||||
|
||||
|
@ -71,7 +75,7 @@ func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.Pr
|
|||
return pkey, nil
|
||||
}
|
||||
|
||||
// Parse PEM encoded PKCS1 or PKCS8 public key
|
||||
// ParseRSAPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key
|
||||
func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
|
||||
var err error
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@ import (
|
|||
var signingMethods = map[string]func() SigningMethod{}
|
||||
var signingMethodLock = new(sync.RWMutex)
|
||||
|
||||
// Implement SigningMethod to add new methods for signing or verifying tokens.
|
||||
// SigningMethod can be used add new methods for signing or verifying tokens.
|
||||
type SigningMethod interface {
|
||||
Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid
|
||||
Sign(signingString string, key interface{}) (string, error) // Returns encoded signature or error
|
||||
Alg() string // returns the alg identifier for this method (example: 'HS256')
|
||||
}
|
||||
|
||||
// Register the "alg" name and a factory function for signing method.
|
||||
// RegisterSigningMethod registers the "alg" name and a factory function for signing method.
|
||||
// This is typically done during init() in the method's implementation
|
||||
func RegisterSigningMethod(alg string, f func() SigningMethod) {
|
||||
signingMethodLock.Lock()
|
||||
|
@ -23,7 +23,7 @@ func RegisterSigningMethod(alg string, f func() SigningMethod) {
|
|||
signingMethods[alg] = f
|
||||
}
|
||||
|
||||
// Get a signing method from an "alg" string
|
||||
// GetSigningMethod retrieves a signing method from an "alg" string
|
||||
func GetSigningMethod(alg string) (method SigningMethod) {
|
||||
signingMethodLock.RLock()
|
||||
defer signingMethodLock.RUnlock()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
checks = ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1023"]
|
|
@ -4,7 +4,7 @@ import (
|
|||
"crypto/rsa"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
func LoadRSAPrivateKeyFromDisk(location string) *rsa.PrivateKey {
|
||||
|
|
22
token.go
22
token.go
|
@ -12,13 +12,13 @@ import (
|
|||
// server uses a different time zone than your tokens.
|
||||
var TimeFunc = time.Now
|
||||
|
||||
// Parse methods use this callback function to supply
|
||||
// Keyfunc will be used by the Parse methods as a callback function to supply
|
||||
// the key for verification. The function receives the parsed,
|
||||
// but unverified Token. This allows you to use properties in the
|
||||
// Header of the token (such as `kid`) to identify which key to use.
|
||||
type Keyfunc func(*Token) (interface{}, error)
|
||||
|
||||
// A JWT Token. Different fields will be used depending on whether you're
|
||||
// Token represents a JWT Token. Different fields will be used depending on whether you're
|
||||
// creating or parsing/verifying a token.
|
||||
type Token struct {
|
||||
Raw string // The raw token. Populated when you Parse a token
|
||||
|
@ -29,7 +29,7 @@ type Token struct {
|
|||
Valid bool // Is the token valid? Populated when you Parse/Verify a token
|
||||
}
|
||||
|
||||
// Create a new Token. Takes a signing method
|
||||
// New creates a new Token. Takes a signing method
|
||||
func New(method SigningMethod) *Token {
|
||||
return NewWithClaims(method, MapClaims{})
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func NewWithClaims(method SigningMethod, claims Claims) *Token {
|
|||
}
|
||||
}
|
||||
|
||||
// Get the complete, signed token
|
||||
// SignedString retrieves the complete, signed token
|
||||
func (t *Token) SignedString(key interface{}) (string, error) {
|
||||
var sig, sstr string
|
||||
var err error
|
||||
|
@ -58,7 +58,7 @@ func (t *Token) SignedString(key interface{}) (string, error) {
|
|||
return strings.Join([]string{sstr, sig}, "."), nil
|
||||
}
|
||||
|
||||
// Generate the signing string. This is the
|
||||
// SigningString generates the signing string. This is the
|
||||
// most expensive part of the whole deal. Unless you
|
||||
// need this for something special, just go straight for
|
||||
// the SignedString.
|
||||
|
@ -82,7 +82,7 @@ func (t *Token) SigningString() (string, error) {
|
|||
return strings.Join(parts, "."), nil
|
||||
}
|
||||
|
||||
// Parse, validate, and return a token.
|
||||
// Parse parses, validates, and returns a token.
|
||||
// keyFunc will receive the parsed token and should return the key for validating.
|
||||
// If everything is kosher, err will be nil
|
||||
func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
|
||||
|
@ -93,12 +93,18 @@ func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token
|
|||
return new(Parser).ParseWithClaims(tokenString, claims, keyFunc)
|
||||
}
|
||||
|
||||
// Encode JWT specific base64url encoding with padding stripped
|
||||
// EncodeSegment encodes a JWT specific base64url encoding with padding stripped
|
||||
//
|
||||
// Deprecated: In a future release, we will demote this function to a non-exported function, since it
|
||||
// should only be used internally
|
||||
func EncodeSegment(seg []byte) string {
|
||||
return base64.RawURLEncoding.EncodeToString(seg)
|
||||
}
|
||||
|
||||
// Decode JWT specific base64url encoding with padding stripped
|
||||
// DecodeSegment decodes a JWT specific base64url encoding with padding stripped
|
||||
//
|
||||
// Deprecated: In a future release, we will demote this function to a non-exported function, since it
|
||||
// should only be used internally
|
||||
func DecodeSegment(seg string) ([]byte, error) {
|
||||
return base64.RawURLEncoding.DecodeString(seg)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue