hawk

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2022 License: MIT Imports: 17 Imported by: 4

README

hawk

Build Status Coverage Status GoDoc

Package hawk supports to use Hawk authentication scheme.

About Hawk: https://github.com/hueniverse/hawk

Installation

go get github.com/hiyosi/hawk

Example

simple client / server

// sample server
package main

import (
	"fmt"
	"time"
	"github.com/hiyosi/hawk"
	"net/http"
)

type credentialStore struct{}

func (c *credentialStore) GetCredential(id string) (*hawk.Credential, error) {
	return &hawk.Credential{
		ID:  id,
		Key: "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
		Alg: hawk.SHA256,
	}, nil
}

var testCredStore = &credentialStore{}

func hawkHandler(w http.ResponseWriter, r *http.Request) {
	s := hawk.NewServer(testCredStore)

	// authenticate client request
	cred, err := s.Authenticate(r)
	if err != nil {
		w.Header().Set("WWW-Authenticate", "Hawk")
		w.WriteHeader(401)
		fmt.Println(err)
		return
	}

	opt := &hawk.Option{
		TimeStamp: time.Now().Unix(),
		Ext:       "response-specific",
	}

	// build server response header
	h, _ := s.Header(r, cred, opt)

	w.Header().Set("Server-Authorization", h)
	w.WriteHeader(200)
	w.Write([]byte("Hello, " + cred.ID))
}

func main() {
	http.HandleFunc("/resource", hawkHandler)
	http.ListenAndServe(":8080", nil)
}
// sample client
package main

import (
	"fmt"
	"time"
	"github.com/hiyosi/hawk"
	"io/ioutil"
	"net/http"
)

func main() {
	c := hawk.NewClient(
		&hawk.Credential{
			ID:  "123456",
			Key: "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
			Alg: hawk.SHA256,
		},
		&hawk.Option{
			TimeStamp: time.Now().Unix(),
			Nonce:     "3hOHpR",
			Ext:       "some-app-data",
		},
	)

	// build request header
	header, _ := c.Header("GET", "http://localhost:8080/resource")
	req, _ := http.NewRequest("GET", "http://localhost:8080/resource", nil)
	req.Header.Set("Authorization", header)

	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	// authenticate server response.
	result, err := c.Authenticate(resp)
	if err != nil {
		fmt.Println("Server Authentication Failure")
	}
	fmt.Println("Server Authentication: ", result)

	b, err := ioutil.ReadAll(resp.Body)
	if err == nil {
		fmt.Println(string(b))
	}
}

build bewit parameter

// server

	b := hawk.NewBewitConfig(
		&hawk.Credential{
			ID:  "123456",
			Key: "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
			Alg: hawk.SHA256,
		},
		10 * time.Minute,
	)


	bewit := b.GetBewit("http://localhost:8080/temp/resource", nil)
	fmt.Println(bewit)

authenticate bewit parameter

// server

func hawkBewitHandler(w http.ResponseWriter, r *http.Request) {
	s := hawk.NewServer(testCredStore)

	cred, err := s.AuthenticateBewit(r)
	if err != nil {
		w.Header().Set("WWW-Authenticate", "Hawk")
		w.WriteHeader(401)
		fmt.Println(err)
		return
	}

	w.WriteHeader(200)
	w.Write([]byte("Access Allow, " + cred.ID))
}

if behind a proxy, you can use an another header field or custom hostname.

  • get host-name by specified header name.
    s := hawk.NewServer(testCredStore)
	s.AuthOption = &hawk.AuthOption{
	    CustomHostNameHeader: "X-Forwarded-Host",
	}
  • or specified hostname value yourself
    s := hawk.NewServer(testCredStore)
    s.AuthOption = &hawk.AuthOption{
	    CustomHostPort: "b.example.com:8888",
	}

See godoc for further documentation

Contribution

  1. Fork (https://github.com/hiyosi/hawk/fork)
  2. Create a feature branch
  3. Commit your changes
  4. Rebase your local changes against the master branch
  5. Run test suite with the go test ./... command and confirm that it passes
  6. Run gofmt -s
  7. Create new Pull Request

License

MIT

Documentation

Overview

Package hawk provides support for Hawk authentication.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Nonce

func Nonce(n int) (string, error)

Types

type Alg

type Alg int
const (
	SHA256 Alg
	SHA512
)

func (Alg) String

func (i Alg) String() string

type AuthOption

type AuthOption struct {
	CustomHostNameHeader string
	CustomHostPort       string
	CustomClock          Clock
	CustomURIHeader      string
}

type AuthType

type AuthType int
const (
	Header AuthType = iota
	Response
	Bewit
)

func (AuthType) String

func (i AuthType) String() string

type BewitConfig

type BewitConfig struct {
	Credential      *Credential
	Ttl             time.Duration
	Ext             string
	LocalTimeOffset time.Duration
}

func NewBewitConfig

func NewBewitConfig(c *Credential, ttl time.Duration) *BewitConfig

func (*BewitConfig) GetBewit

func (b *BewitConfig) GetBewit(url string, clock Clock) string

GetBewit builds a value of bewit parameter.

type Client

type Client struct {
	Credential *Credential
	Option     *Option
}

func NewClient

func NewClient(c *Credential, o *Option) *Client

func (*Client) Authenticate

func (c *Client) Authenticate(res *http.Response) (bool, error)

Authenticate authenticate the Hawk server response from the HTTP response. Successful case returns true.

func (*Client) Header

func (c *Client) Header(method, uri string) (string, error)

Header builds a value to be set in the Authorization header.

type Clock

type Clock interface {
	// Now returns the current unix-time obtained by adding a offset value.
	Now(offset time.Duration) int64
}

Clock returns a time.

type Credential

type Credential struct {
	ID  string
	Key string
	Alg Alg
}

type CredentialStore

type CredentialStore interface {
	GetCredential(id string) (*Credential, error)
}

type LocalClock

type LocalClock struct{}

func (*LocalClock) Now

func (c *LocalClock) Now(offset time.Duration) int64

type Mac

type Mac struct {
	Type       AuthType
	Credential *Credential
	Uri        string
	Method     string
	HostPort   string
	Option     *Option
}

func (*Mac) String

func (m *Mac) String() (string, error)

String returns a base64 encoded message authentication code.

type NonceValidator

type NonceValidator interface {
	Validate(key, nonce string, ts int64) bool
}

type Option

type Option struct {
	TimeStamp   int64
	Nonce       string
	Payload     string
	ContentType string
	Hash        string
	Ext         string
	App         string
	Dlg         string
}

type PayloadHash

type PayloadHash struct {
	ContentType string
	Payload     string
	Alg         Alg
}

func (*PayloadHash) String

func (h *PayloadHash) String() string

String returns a base64 encoded hash value of payload

type Server

type Server struct {
	CredentialStore CredentialStore
	NonceValidator  NonceValidator
	TimeStampSkew   time.Duration
	LocaltimeOffset time.Duration
	Payload         string
	AuthOption      *AuthOption
}

func NewServer

func NewServer(cs CredentialStore) *Server

NewServer initializies a new Server.

func (*Server) Authenticate

func (s *Server) Authenticate(req *http.Request) (*Credential, error)

Authenticate authenticate the Hawk request from the HTTP request. Successful case returns credential information about requested user.

func (*Server) AuthenticateBewit

func (s *Server) AuthenticateBewit(req *http.Request) (*Credential, error)

AuthenticateBewit authenticate the Hawk bewit request from the HTTP request. Successful case returns credential information about requested user.

func (*Server) Header

func (s *Server) Header(req *http.Request, cred *Credential, opt *Option) (string, error)

Header builds a value to be set in the Server-Authorization header.

type TsMac

type TsMac struct {
	TimeStamp  int64
	Credential *Credential
}

func (*TsMac) String

func (tm *TsMac) String() string

String returns a base64 encoded message authentication code for timestamp

Jump to

Keyboard shortcuts

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