jwt

package
v1.2.2 Latest Latest
Warning

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

Go to latest
Published: Feb 10, 2021 License: Apache-2.0 Imports: 11 Imported by: 3

README

JWT Security

This package contains functions and types for enabling JWT as a security mechanism in a microservice. It integrates with Goa generated JWT security and also as part of the SecurityChain.

Setting up a JWT security

There are a couple of things you need to do to enable the JWT security middleware. For details on JWT you can find many resources on the official site: http://jwt.io.

JWT has two main parts: issuing JWT tokens (with claims) and verifying the tokens. This package provides means of validating a JWT token with claims by using secret keys (RSA key pairs).

Setting up the secret keys

Create a directory in which you'll keep your key-pair:

mkdir rsa-keys
cd rsa-keys

The generate 2048-bit RSA key pair:

openssl genrsa -des3 -out private.pem 2048

The output the keys in PEM form:

openssl rsa -in private.pem -outform PEM -pubout -out public.pub

NOTE: Make sure that the public key ends in .pub. This is how the default key resolver of the library locates the public keys.

Set up JWT with Goagen

To use the JWT security you need to set up JWT security in your microservice Goa DSL.

In your design file, add the JWT setup:

var JWTAuth = JWTSecurity("JWT", func() {
	Header("Authorization")
	Scope("api:read", "Read access to the API")
	Scope("api:write", "Write access to the API")
})

var _ = Resource("user", func() {
	BasePath("/user")

	// Other specification here ...

  Security(JWTAuth) // Add the JWTAuth to this resource
})

By running goagen ... on the deisgn again, you'll notice that Goa will add a security file app/security.go.

More details on how to configure the JWT security are available on the official documentation:

The most important thing there is the security specification scheme - the following function that builds JWTSecurity:

// NewJWTSecurity creates a JWT security definition.
func NewJWTSecurity() *goa.JWTSecurity {
	def := goa.JWTSecurity{
		In:       goa.LocHeader,
		Name:     "Authorization",
		TokenURL: "",
		Scopes: map[string]string{
			"api:read":  "Read access to the API",
			"api:write": "Write access to the API",
		},
	}
	return &def
}

We'll use this in the next step.

Setting up a SecurityChain

Once the security specs are generated by Goa, you need to set up a security chain for the microservice.

In the main.go file of your microservice, set up the JWT Security Chain middleware and add it to the security chain.

import (
  // other imports
  "githib.com/Microkubes/microservice-security/auth"
  "githib.com/Microkubes/microservice-security/chain"
  "githib.com/Microkubes/microservice-security/jwt"
)
func main(){
  // "secret-keys" is the directory containing the RSA keys
  // app.NewJWTSecurity() creates the JWTSecurity scheme structure
  JWTMiddleware := jwt.NewJWTSecurity("secret-keys", app.NewJWTSecurity())


  sc := chain.NewSecurityChain(). // create new chain
    AddMiddleware(JWTMiddleware). // Add the JWT middleware
    AddMiddleware(chain.CheckAuthMiddleware) // add the check for authentication

  // other initializations here...

  service.Use(chain.ToGoaMiddleware(sc)) // attach the security chain as Goa middleware

}

Testing the setup

To test the setup, you'll need to generate and sign a JWT token, then use it in the request header.

To generate a JWT, you can use different tools. In this example we'll use jwtgen command line tool. To install it:

npm install -g jwtgen

Then, to generate the JWT token, type:

jwtgen -a RS256\
       -p secret-keys/private.pem\
       -c "userId=9479e3b6-a4c5-445c-aefe-c84b5a47ed3c" \
       -c "username=test-user"\
       -c "roles=user,admin"\
       -c "organizations=Org1,Org2"

which will output the JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1MDIyOTA3NDYsInVzZXJJZCI6Ijk0Nzl
lM2I2LWE0YzUtNDQ1Yy1hZWZlLWM4NGI1YTQ3ZWQzYyIsInVzZXJuYW1lIjoidGVzdC11c2VyIiwicm9
sZXMiOiJ1c2VyLGFkbWluIiwib3JnYW5pemF0aW9ucyI6Ik9yZzEsT3JnMiJ9.J2dFSUChwAyy3g92qj
6ggT-EA_B-kv16cjyEQS0xBTHl6Sw3vhsaooRTnFDkXKVeGqnctyjRLGmRxpQCYZ5FVnJocSCKw99Q1k
mr-HbyoLjjpppYOSC_LOyPPqmUe1M9ze5GOP_QY9H5V6g6Otar_Ge4tXoR9P7_px7KtHJ2jINeX_amxW
MnujN5fqsrI80wNSGcGTKwU2FSJynQoS_7zziHmCK0h1m-XV_wjaMu4h-_nHsK5pNAF1R7uWx20aAsg4
38wVjwdMmgDhRJOlctLwhFlthAr_GXYKDH-ztKGz6KNXRfUK8--ad4TaNgCDzbjVkHrgMLS-RatUXXoW
4pfw

(Note that the JWT is actually one line. For readability purposes it is displayed here in multiple lines.)

Then you'll need to add the token in the Authorization HTTP header of the request.

curl --header "Authorization: Bearer eyJ0eXAiOiJKV1Q...<full token here>...4pfw" "http://localhost:8080/user/1"

Documentation

Index

Constants

View Source
const JWTSecurityType = "JWT"

JWTSecurityType is the name of the JWT security type

Variables

View Source
var AvailableSigningMethods = SigningMethods{
	"RS256": jwtgo.SigningMethodRS256,
	"RS384": jwtgo.SigningMethodRS384,
	"RS512": jwtgo.SigningMethodRS512,
}

AvailableSigningMethods holds the supported signing methods.

Functions

func LoadJWTPublicKeys

func LoadJWTPublicKeys(path string) ([]goajwt.Key, error)

LoadJWTPublicKeys loads PEM encoded RSA public keys used to validate and decrypt the JWT.

func NewJWTSecurity

func NewJWTSecurity(keysDir string, scheme *goa.JWTSecurity) chain.SecurityChainMiddleware

NewJWTSecurity creates a JWT SecurityChainMiddleware using a simple key resolver that loads the public keys from the keysDir. The key files must end in *.pub. The scheme is obtained from the generated Goadesign JWT security.

func NewJWTSecurityMiddleware

func NewJWTSecurityMiddleware(resolver goajwt.KeyResolver, scheme *goa.JWTSecurity) chain.SecurityChainMiddleware

NewJWTSecurityMiddleware creates a new chain.SecurityChainMiddleware with a given KeyResolver and JWTSecurity configuration. As resolver you may pass the simple key resolver created with NewKeyResolver or you may pass a more sophisticated key-resolver. The scheme is obtained from the generated Goadesign JWT security.

func NewKeyResolver

func NewKeyResolver(path string) (goajwt.KeyResolver, error)

NewKeyResolver creates a simple key resolver for the JWT middleware. It loads the public keys from a specified directory (path). The public key files MUST end in *.pub .

func SignToken

func SignToken(claims map[string]interface{}, signingMethod string, key interface{}) (string, error)

SignToken singns a JWT token with the given claims using the provided private key with the signingMethod.

Types

type SigningMethods

type SigningMethods map[string]jwtgo.SigningMethod

SigningMethods is a map mapping from a signing method name to an actual SigningMethod

Jump to

Keyboard shortcuts

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