Documentation ¶
Overview ¶
Package multipass implements an authentication service which can be used to wrap any http.Handler(Func).
Multipass implements the concept to authenticate users based on something they own instead of something they know. This is better known as the second factor of Two-factor Authentication.
Quick Start ¶
Wrap any http.Handler or http.HandlerFunc to provide user authentication. In the example below, the appHandler function is wrapped using the AuthHandler wrapper. It assumes you have a SMTP service running on `localhost:2525` and user identified by email address leeloo@dallas has access to the resource at `/private`.
package main import ( "fmt" "log" "net/http" "github.com/namsral/multipass" "github.com/namsral/multipass/services/email" ) func appHandler(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/": fmt.Fprintf(w, "this is the public page") return case "/private": fmt.Fprintf(w, "this is the private page") return } http.NotFound(w, r) } func main() { options := &email.Options{ Addr: "localhost:2525", // SMTP address FromAddr: "Multipass Bot <noreply@dallas>", } service, err := email.NewUserService(options) if err != nil { log.Fatal(err) } service.AddPattern("/private") // Accessible to authenticated users service.Register("leeloo@dallas") // Only registered users are granted access addr := "localhost:6080" siteaddr := "http://" + addr m, err := multipass.NewMultipass(siteaddr) if err != nil { log.Fatal(err) } m.SetUserService(service) // Override the default UserService h := multipass.AuthHandler(http.HandlerFunc(appHandler), m) log.Fatal(http.ListenAndServe(addr, h)) }
The package consist of three major components; Multipass, ResourceHandler and UserService.
Multipass ¶
Multipass is a http.Handler which issues and signs user tokens and validates their signature.
NewMultipass(siteaddr string) (*Multipass, error)
Multipass has it's own web UI which is available at the configurable basepath. From the web UI users can request a login url to gain access to private resources.
Multipass.SetBasePath(basepath string)
UserService ¶
User authorization is offloaded to the UserService service. Because the UserService is an interface custom UserService's can be developed and plugged into the Multipass instance. Allowing other means of authentication and authorization besides the built-in email UserService.
// A UserService is an interface used by a Multipass instance to register, // list user handles and notify users about requested access tokens. // A handle is a unique user identifier, e.g. email address. type UserService interface { // Register returns nil when the given handle is accepted for // registration with the service. // The handle is passed on by the Multipass instance and can represent // an username, email address or even an URI representing a connection to // a datastore. The latter allows the UserService to be associated // with a RDBMS from which to verify listed users. Register(handle string) error // Listed returns true when the given handle is listed with the // service. Listed(handle string) bool // Authorized returns true when the user identified by the given handle is // authorized to access the given resource at rawurl. Authorized(handle, rawurl string) bool // Notify returns nil when the given login URL is successfully // communicated to the given handle. Notify(handle, loginurl string) error // Close closes any open connections. Close() error }
An implementation can be found in the `services/email` package. This implementations identifies users by their email address.
ResourceHandler ¶
ResourceHandler accepts a http.ResponseWriter and http.Request and determines if the request is from an authenticated user and if this user is authorized to access the requested resource according to the UserService. The ResourceHandler extracts any user token from the header, cookie header or query parameters and validates the user tokens signature with preset or pre-generated key pairs.
ResourceHandler(w http.ResponseWriter, r *http.Request, m *Multipass) (int, error)
Index ¶
Constants ¶
const (
PKENV = "MULTIPASS_RSA_PRIVATE_KEY"
)
Portable constants
Variables ¶
var ( ErrInvalidToken = errors.New("invalid token") ErrForbidden = errors.New(http.StatusText(http.StatusForbidden)) )
Portable errors
var DefaultUserService = io.NewUserService(os.Stdout)
DefaultUserService is the default UserService used by Multipass.
Functions ¶
func AuthHandler ¶ added in v0.3.0
AuthHandler wraps any http.Handler to provide authentication using the given Multipass instance. Handlers from other http routers can be wrapped with little effort by copying the AuthHandler and make minor changes.
func NewLoginURL ¶
NewLoginURL returns a login url which can be used as a time limited login. Optional values will be encoded in the login URL.
func ResourceHandler ¶ added in v0.3.0
ResourceHandler validates the token in the request before it writes the response.
Types ¶
type Multipass ¶
Multipass implements the http.Handler interface which can handle authentication and authorization of users and resources using signed JWT.
func NewMultipass ¶
NewMultipass returns a new instance of Multipass with reasonalble defaults: 2048 bit RSA key pair, `/multipass` basepath a token expiration time of 24 hours.
func (*Multipass) AccessToken ¶
AccessToken returns a new signed and serialized token with the given handle as a claim.
func (*Multipass) ServeHTTP ¶
func (m *Multipass) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP satisfies the ServeHTTP interface
func (*Multipass) SetBasePath ¶ added in v0.3.0
SetBasePath overrides the default base path of `/multipass`. The given basepath is made absolute before it is set.
func (*Multipass) SetUserService ¶ added in v0.3.0
func (m *Multipass) SetUserService(s UserService)
SetUserService overrides the default UserService.
type UserService ¶ added in v0.3.0
type UserService interface { // Register returns nil when the given handle is accepted for // registration with the service. // The handle is passed on by the Multipass instance and can represent // an username, email address or even an URI representing a connection to // a datastore. The latter allows the UserService to be associated // with a RDBMS from which to verify listed users. Register(handle string) error // Listed returns true when the given handle is listed with the // service. Listed(handle string) bool // Authorized returns true when the user identified by the given handle is // authorized to access the given resource at rawurl. Authorized(handle, rawurl string) bool // Notify returns nil when the given login URL is successfully // communicated to the given handle. Notify(handle, loginurl string) error // Close closes any open connections. Close() error }
A UserService is an interface used by a Multipass instance to register, list user handles and notify users about requested access tokens. A handle is a unique user identifier, e.g. email address.