jwt

package module
v2.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 19, 2023 License: Apache-2.0 Imports: 10 Imported by: 2

README

jwt

ci GoDoc GitHub issues GitHub forks GitHub stars GitHub license

JWT Signer and Verifier for RSA Signed Tokens.

Installation

go get -u github.com/na4ma4/jwt/v2

Example

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/na4ma4/jwt"
)

func main() {
    // Generate Token from authentication service.

    // Create signer using RSA private key in PEM format (no passphrase)
    signer, err := jwt.NewRSASignerFromFile("key.pem")
    if err != nil {
        log.Panic(err)
    }

    // Sign list of claims as a token
    token, err := signer.SignClaims(
        jwt.String(jwt.Subject, "user100"),
        jwt.String(jwt.Audience, "myservice"),
        jwt.Time(jwt.Issued, time.Now()),
        jwt.Time(jwt.NotBefore, time.Now()),
        jwt.Time(jwt.Expires, time.Now().Add(time.Hour)),
    )
    if err != nil {
        log.Panic(err)
    }

    // Give token to client
    fmt.Printf("Token: %s\n", token)

    //
    // Verify on remote service using only the public certificate.
    //

    // Create verifier using certificate in PEM format
    verifier, err := jwt.NewRSAVerifierFromFile("myservice", "cert.pem")
    if err != nil {
        log.Panic(err)
    }

    // Verify token has a valid signature and the audience matches this service
    result, err := verifier.Verify(token)
    if err != nil {
        log.Panic(err)
    }

    // Result contains Subject(username), Audience and other useful data, but just verifier.Verify not throwing an error is enough for validity.
    fmt.Printf("Username: %s\n", result.Subject)
    fmt.Printf("Service: %s\n", result.Audiences[0])
}

Documentation

Documentation is hosted at GoDoc project.

License

JWT package released under Apache License 2.0. See LICENSE for details.

Documentation

Overview

Package jwt provides a signing and verifier implementation using RSA keys.

Index

Constants

View Source
const (
	// Issuer is the IANA Registered claim for JWT issuer.
	Issuer string = "iss"
	// Subject is the IANA Registered claim for JWT subject.
	Subject string = "sub"
	// Audience is the IANA Registered claim for JWT audience.
	Audience string = "aud"
	// Expires is the IANA Registered claim for JWT expiry time.
	Expires string = "exp"
	// NotBefore is the IANA Registered claim for JWT not before time.
	NotBefore string = "nbf"
	// Issued is the IANA Registered claim for JWT issue time.
	Issued string = "iat"
	// ID is the IANA Registered claim for JWT ID.
	ID string = "jti"
)
View Source
const (
	// RS256 RSASSA-PKCS1-v1_5 with SHA-256.
	RS256 = pascaljwt.RS256
	// RS384 RSASSA-PKCS1-v1_5 with SHA-348.
	RS384 = pascaljwt.RS384
	// RS512 RSASSA-PKCS1-v1_5 with SHA-512.
	RS512 = pascaljwt.RS512
)

Variables

View Source
var ErrClaimFormatInvalid = errors.New("claim format is invalid")

ErrClaimFormatInvalid is returned when a claim format is invalid.

View Source
var ErrExtractPublicKey = errors.New("unable to extract public key")

ErrExtractPublicKey is returned if the public key failed to get extracted from a valid certificate file.

View Source
var ErrInvalidClaimType = errors.New("invalid claim type")

ErrInvalidClaimType is returned when an operation tries to return an invalid claim type.

View Source
var ErrInvalidTypeForClaim = errors.New("invalid type for registered claim")

ErrInvalidTypeForClaim is returned when a registered claim is using an invalid type.

View Source
var ErrTokenInvalidAudience = errors.New("invalid token audience")

ErrTokenInvalidAudience is the error returned when an audience does not match the token.

View Source
var ErrTokenTimeNotValid = errors.New("token time is not valid")

ErrTokenTimeNotValid is the general error returned when a token is outside the NotBefore or Expires times.

View Source
var ErrUnsupportedClaimType = errors.New("unsupported claim type")

ErrUnsupportedClaimType is returned when an unsupported claim type is used.

Functions

func ConstructClaimsFromSlice

func ConstructClaimsFromSlice(claims ...Claim) (*pascaljwt.Claims, error)

ConstructClaimsFromSlice takes a slice of `Claim`s and returns a prepared `pascaljwt.Claims` pointer, or an error if construction failed.

func ParsePKCS1PrivateKey

func ParsePKCS1PrivateKey(data []byte) (*rsa.PrivateKey, error)

ParsePKCS1PrivateKey parses a PKCS1 Private Key from a byte slice containing an RSA key in PEM format.

func ParsePKCS1PrivateKeyFromFile

func ParsePKCS1PrivateKeyFromFile(filename string) (*rsa.PrivateKey, error)

ParsePKCS1PrivateKeyFromFile parses a PKCS1 Private Key from a PEM file.

func ParsePKCS1PrivateKeyFromFileAFS

func ParsePKCS1PrivateKeyFromFileAFS(afs afero.Fs, filename string) (*rsa.PrivateKey, error)

ParsePKCS1PrivateKeyFromFileAFS parses a PKCS1 Private Key from a PEM file with a supplied `afero.Fs`.

func ParsePKCS1PublicKey

func ParsePKCS1PublicKey(data []byte) (*rsa.PublicKey, error)

ParsePKCS1PublicKey parses a PKCS1 Public Certificate from a byte slice containing a PEM certificate.

func ParsePKCS1PublicKeyFromFile

func ParsePKCS1PublicKeyFromFile(filename string) (*rsa.PublicKey, error)

ParsePKCS1PublicKeyFromFile parses a PKCS1 Public Certificate from a PEM file.

func ParsePKCS1PublicKeyFromFileAFS

func ParsePKCS1PublicKeyFromFileAFS(afs afero.Fs, filename string) (*rsa.PublicKey, error)

ParsePKCS1PublicKeyFromFileAFS parses a PKCS1 Public Certificate from a PEM file with a supplied `afero.Fs`.

func Sign

func Sign(
	signer Signer,
	audience []string,
	subject string,
	online bool,
	notBefore, expiry time.Time,
) ([]byte, error)

Sign takes a signer, subject, audience, online status, notBefore and expiry and produces a signed token.

Types

type AudienceSlice

type AudienceSlice []string

AudienceSlice is a helper type for taking a slice of strings and allowing it to be checked for valid audiences.

func (AudienceSlice) Has

func (a AudienceSlice) Has(audience string) bool

Has checks to see if an AudienceSlice contains a specific audience.

func (AudienceSlice) HasAll

func (a AudienceSlice) HasAll(audiences []string) bool

HasAll checks to see if all audiences supplied is matched by any audience in the slice. if supplied audience list is empty, returns false.

func (AudienceSlice) HasAny

func (a AudienceSlice) HasAny(audiences []string) bool

HasAny checks to see if any audience supplied is matched by any audience in the slice.

func (AudienceSlice) HasOnly

func (a AudienceSlice) HasOnly(audiences []string) bool

HasOnly checks to see if all audiences supplied is matched by all audience in the slice. if supplied audience list is empty, returns false.

func (AudienceSlice) Slice

func (a AudienceSlice) Slice() []string

Slice returns the AudienceSlice as the underlying string slice.

type Claim

type Claim struct {
	Key       string
	Type      ClaimType
	Integer   int64
	String    string
	Interface interface{}
}

A Claim is a marshaling operation used to add a key-value pair to a tokens context. Most claims are lazily marshaled, so it's inexpensive to add claims to disabled debug-level log statements.

func Any

func Any(key string, value interface{}) Claim

Any takes a key and an arbitrary value and chooses the best way to represent them as a field, falling back to a reflection-based approach only if necessary.

Since byte/uint8 and rune/int32 are aliases, Any can't differentiate between them. To minimize surprises, []byte values are treated as binary blobs, byte values are treated as uint8, and runes are always treated as integers.

func Bool

func Bool(key string, val bool) Claim

Bool constructs a field with the given key and value.

func Int

func Int(key string, val int) Claim

Int constructs a field with the given key and value.

func Int64

func Int64(key string, val int64) Claim

Int64 constructs a field with the given key and value.

func Reflect

func Reflect(key string, val interface{}) Claim

Reflect constructs a field with the given key and an arbitrary object. It uses an encoding-appropriate, reflection-based function to lazily serialize nearly any object into the logging context, but it's relatively slow and allocation-heavy. Outside tests, Any is always a better choice.

If encoding fails (e.g., trying to serialize a map[int]string to JSON), Reflect includes the error message in the final log output.

func String

func String(key, val string) Claim

String constructs a field with the given key and value.

func Strings

func Strings(key string, val []string) Claim

Strings constructs a field with the given key and value.

func Time

func Time(key string, val time.Time) Claim

Time constructs a field with the given key and value.

func (*Claim) Field

func (c *Claim) Field() string

Field returns the JWT compatible field from some useful longer names.

func (*Claim) IsRegistered

func (c *Claim) IsRegistered() bool

IsRegistered returns true if the Key is a IANA registered "JSON Web Token Claims".

func (*Claim) Time

func (c *Claim) Time() (time.Time, error)

Time returns the time value of the `Field` or an error if it is not a `TimeType`.

type ClaimType

type ClaimType uint8

A ClaimType indicates which member of the Field union struct should be used and how it should be serialized.

const (
	// UnknownType is the default, this will throw an error.
	UnknownType ClaimType = iota
	// ArrayMarshalerType indicates that the field carries an ArrayMarshaler.
	ArrayMarshalerType
	// ObjectMarshalerType indicates that the field carries an ObjectMarshaler.
	ObjectMarshalerType
	// BinaryType indicates that the field carries an opaque binary blob.
	BinaryType
	// BoolType indicates that the field carries a bool.
	BoolType
	// ByteStringType indicates that the field carries UTF-8 encoded bytes.
	ByteStringType
	// Complex128Type indicates that the field carries a complex128.
	Complex128Type
	// Complex64Type indicates that the field carries a complex128.
	Complex64Type
	// DurationType indicates that the field carries a time.Duration.
	DurationType
	// Float64Type indicates that the field carries a float64.
	Float64Type
	// Float32Type indicates that the field carries a float32.
	Float32Type
	// Int64Type indicates that the field carries an int64.
	Int64Type
	// Int32Type indicates that the field carries an int32.
	Int32Type
	// Int16Type indicates that the field carries an int16.
	Int16Type
	// Int8Type indicates that the field carries an int8.
	Int8Type
	// StringType indicates that the field carries a string.
	StringType
	// StringsType indicates that the field carries a string slice.
	StringsType
	// TimeType indicates that the field carries a time.Time.
	TimeType
	// Uint64Type indicates that the field carries a uint64.
	Uint64Type
	// Uint32Type indicates that the field carries a uint32.
	Uint32Type
	// Uint16Type indicates that the field carries a uint16.
	Uint16Type
	// Uint8Type indicates that the field carries a uint8.
	Uint8Type
	// UintptrType indicates that the field carries a uintptr.
	UintptrType
	// ReflectType indicates that the field carries an interface{}, which should
	// be serialized using reflection.
	ReflectType
	// NamespaceType signals the beginning of an isolated namespace. All
	// subsequent fields should be added to the new namespace.
	NamespaceType
	// StringerType indicates that the field carries a fmt.Stringer.
	StringerType
	// ErrorType indicates that the field carries an error.
	ErrorType
	// SkipType indicates that the field is a no-op.
	SkipType
)

Type list borrowed from uber-go/zap.

type RSASigner

type RSASigner struct {
	PrivateKey *rsa.PrivateKey
	Issuer     string
	Algorithm  string
}

RSASigner implements the `Signer` interface and creates a token signed with RSA public/private keys.

func (*RSASigner) SignClaims

func (r *RSASigner) SignClaims(claims ...Claim) ([]byte, error)

SignClaims takes a list of claims and produces a signed token.

type RSAVerifier

type RSAVerifier struct {
	PublicKey *rsa.PublicKey
	Issuer    string
	Audiences []string
}

RSAVerifier implements the `Verifier` interface and tests a token signed with RSA public/private keys.

func (*RSAVerifier) Verify

func (v *RSAVerifier) Verify(token []byte) (VerifyResult, error)

Verify takes the token and checks it's signature against the RSA public key, and the audience, notbefore and expires validity.

type Signer

type Signer interface {
	SignClaims(claims ...Claim) ([]byte, error)
}

Signer produces a token from a supplied subject and audience with notbefore and expiry times.

func NewRSASignerFromFile

func NewRSASignerFromFile(filename string) (Signer, error)

NewRSASignerFromFile returns an `RSASigner` initialized with the RSA Private Key supplied.

type Verifier

type Verifier interface {
	// Verify processes a supplied token
	Verify(token []byte) (VerifyResult, error)
}

Verifier takes a token and returns the subject if it is valid, or an error if it is not.

func NewRSAVerifierFromFile

func NewRSAVerifierFromFile(audiences []string, filename string) (Verifier, error)

NewRSAVerifierFromFile returns an `RSAVerifier` initialized with the RSA Public Key supplied and an audience for token verification.

type VerifyResult

type VerifyResult struct {
	ID             string
	IsOnline       bool
	Subject        string
	Audience       AudienceSlice
	ClaimAudiences AudienceSlice
	Fingerprint    string
	NotBefore      time.Time
	Expires        time.Time
	Claims         map[string]Claim
}

VerifyResult returns the information about the token verification.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL