jwt

package module
v2.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2021 License: Apache-2.0 Imports: 10 Imported by: 2

README

koshatul/jwt

Build Status GoDoc

JWT Signer and Verifier for RSA Signed Tokens.

Installation

go get -u github.com/koshatul/jwt

Example

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/koshatul/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

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 = jwt.RS256
	// RS384 RSASSA-PKCS1-v1_5 with SHA-348.
	RS384 = jwt.RS384
	// RS512 RSASSA-PKCS1-v1_5 with SHA-512.
	RS512 = jwt.RS512
)

Variables

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 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.

Functions

func ConstructClaimsFromSlice

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

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

Duplicate keys will we overridden in order of apearance!

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,
	subject,
	audience 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.

func SignFingerprint

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

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

Types

type Claim

type Claim struct {
	Key       string
	Type      ClaimType
	Integer   int64
	Uinteger  uint64
	Float     float64
	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 claim, 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 claim with the given key and value.

func Float

func Float(key string, val float64) Claim

Float constructs a claim with the given key and value.

func Int

func Int(key string, val int64) Claim

Int constructs a claim with the given key and value.

func Reflect

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

Reflect constructs a claim 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 claim with the given key and value.

func Time

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

Time constructs a claim with the given key and value.

func Uint

func Uint(key string, val uint64) Claim

Uint constructs a claim 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 `Claim` 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
	// 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. Duplicate keys will we overridden in order of apearance! The issuer defaults to r.Issuer.

type RSAVerifier

type RSAVerifier struct {
	PublicKey *rsa.PublicKey
	Issuer    string
	Audience  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(audience, 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
	Audiences   []string
	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