tlsserver

package
v0.0.0-...-4ab42d6 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2021 License: MIT Imports: 14 Imported by: 3

README

httpauthenticator

This package provides a wrapper around the http request and authenticates the sender of the request.

Server Usage

NewAuthenticator provides a handler that verifies provided credentials supporting multiple protocols.

  • Client Certificate authentication

    The client includes a client certificate in its TLS connection that includes its clientID in the CN and role in the OU field. The certificate is signed by the Hub CA.

  • BASIC authentication. See also: https://www.alexedwards.net/blog/basic-authentication-in-go

    Parse the Authorization header, where base64 is a function that encodes the "username:password" string in base64 format.

    Authorization: Basic base64("username:password")

  • DIGEST authentication

    1. Client performs GET request
    2. Server responds with 401, header: WWW-authenticate: Digest, and fields real, qop, algorithm, none and opaque.
    3. Client gets login credentials username and password from user
    4. Client repeats request including the header: "Authorization: Digest username="", realm=, nonce=, qop=, opaque=, algorithm=, response=, cnonce=, userhash=
  • JWT authentication

    The client makes a login request providing its credentials and a requested Hash algorithm. The server returns a bearer token which is a hash of The default hash is MD5. A different algorithm can be configured. All future request include a Authentication header with bearer token:

    Authorization: Bearer asldkasdwerpwoierwperowepr

pwStore := unpwstore.NewPasswordFileStore(path)
httpAuthenticator := authenticator.NewHttpAuthenticator(pwStore)
router.HandleFunc(path, httpauth.NewAuthHandler(httpAuthenticator.Authenticate))

For JWT authentication also add a login handler to obtain a token

router.HandleFunc("/login", httpauth.LoginHandler)

Client Usage

... todo .. describe authentication clients

Documentation

Overview

Package servetls with TLS server for use by plugins and testing

Index

Constants

View Source
const JwtRefreshCookieName = "authtoken"

Variables

This section is empty.

Functions

This section is empty.

Types

type BasicAuthenticator

type BasicAuthenticator struct {
	// contains filtered or unexported fields
}

BasicAuthenticator decodes the authentication method used in the request and authenticates the user

func NewBasicAuthenticator

func NewBasicAuthenticator(verifyUsernamePassword func(loginID, secret string) bool) *BasicAuthenticator

NewBasicAuthenticator creates a new HTTP Basic authenticator

verifyUsernamePassword is the handler that validates the loginID and secret

func (*BasicAuthenticator) AuthenticateRequest

func (bauth *BasicAuthenticator) AuthenticateRequest(resp http.ResponseWriter, req *http.Request) (userID string, match bool)

AuthenticateRequest Checks in order: client certificate, JWT bearer, Basic Returns the authenticated userID or an error if authentication failed

type CertAuthenticator

type CertAuthenticator struct {
}

CertAuthenticator verifies the client certificate authentication is used This simply checks if a client certificate is active and assumes that having one is sufficient to pass auth

func NewCertAuthenticator

func NewCertAuthenticator() *CertAuthenticator

NewCertAuthenticator creates a new HTTP authenticator Use .AuthenticateRequest() to authenticate the incoming request

func (*CertAuthenticator) AuthenticateRequest

func (hauth *CertAuthenticator) AuthenticateRequest(resp http.ResponseWriter, req *http.Request) (userID string, ok bool)

AuthenticateRequest The real check happens by the TLS server that verifies it is signed by the CA. If the certificate is a plugin, then no userID is returned Returns the userID of the certificate (CN) or an error if no client certificate is used

type HttpAuthenticator

type HttpAuthenticator struct {
	BasicAuth *BasicAuthenticator
	CertAuth  *CertAuthenticator
	JwtAuth   *JWTAuthenticator
}

HttpAuthenticator chains the selected authenticators

func NewHttpAuthenticator

func NewHttpAuthenticator() *HttpAuthenticator

NewHttpAuthenticator creates a container to apply HTTP request authenticators By default the certificate authenticator is enabled. Additional authenticators can be enabled using the Enable... functions

Use .AuthenticateRequest() to authenticate the incoming request

func (*HttpAuthenticator) AuthenticateRequest

func (hauth *HttpAuthenticator) AuthenticateRequest(resp http.ResponseWriter, req *http.Request) (userID string, match bool)

AuthenticateRequest Checks in order: client certificate, JWT bearer, Basic Returns the authenticated userID or an error if authentication failed

func (*HttpAuthenticator) EnableBasicAuth

func (hauth *HttpAuthenticator) EnableBasicAuth(validateCredentials func(loginName string, password string) bool)

EnableBasicAuth enables BASIC authentication Basic auth is a legacy authentication scheme and not recommended as it requires each service to have access to the credentials store. Use of JwtAuth is preferred.

validateCredentials is the function that verifies the given credentials

func (*HttpAuthenticator) EnableJwtAuth

func (hauth *HttpAuthenticator) EnableJwtAuth(verificationKey *ecdsa.PublicKey)

EnableJwtAuth enables JWT authentication using asymmetric keys JWT tokens are included in the request header authorization field and signed by an issuing authentication server using the server's private key. The provided verification key is the server's public key needed to verify that signature.

type JWTAuthenticator

type JWTAuthenticator struct {
	// contains filtered or unexported fields
}

JWTAuthenticator verifies issued JWT tokens using the provided public certificate The application must use .AuthenticateRequest() to authenticate the incoming request using the access token.

func NewJWTAuthenticator

func NewJWTAuthenticator(publicKey *ecdsa.PublicKey) *JWTAuthenticator

NewJWTAuthenticator creates a new JWT authenticator publicKey is the public key for verifying the private key signature

func (*JWTAuthenticator) AuthenticateRequest

func (jauth *JWTAuthenticator) AuthenticateRequest(resp http.ResponseWriter, req *http.Request) (userID string, match bool)

AuthenticateRequest validates the access token The access token is provided in the request header using the Bearer schema:

Authorization: Bearer <token>

Returns the authenticated user and true if there is a match, of false if authentication failed

func (*JWTAuthenticator) DecodeToken

func (jauth *JWTAuthenticator) DecodeToken(tokenString string) (
	jwtToken *jwt.Token, claims *JwtClaims, err error)

DecodeToken and return its claims

If the token is invalid then claims will be empty and an error is returned If the token is valid but has an incorrect signature, the token and claims will be returned with an error

type JWTIssuer

type JWTIssuer struct {

	// These can be modified at will
	AccessTokenValidity  time.Duration
	RefreshTokenValidity time.Duration
	// contains filtered or unexported fields
}

JWTIssuer issues JWT tokens

func NewJWTIssuer

func NewJWTIssuer(
	issuerName string,
	signingKey *ecdsa.PrivateKey,
	verifyUsernamePassword func(loginID, secret string) bool,
) *JWTIssuer

NewJWTIssuer create a new issuer of JWT authentication tokens using asymmetric keys.

issuerName of the service issuing the token
signingKey for generating tokens, or nil to generate a random 64 byte secret
verifyUsernamePassword is the handler that validates the login credentials

func (*JWTIssuer) CreateJWTTokens

func (issuer *JWTIssuer) CreateJWTTokens(userID string) (accessToken string, refreshToken string, err error)

CreateJWTTokens creates a new access and refresh token pair containing the userID. The result is written to the response and a refresh token is set securely in a client cookie.

userID is the login ID of the user to whom the token is assigned and will be included in the claims

func (*JWTIssuer) DecodeToken

func (issuer *JWTIssuer) DecodeToken(tokenString string) (
	jwtToken *jwt.Token, claims *JwtClaims, err error)

DecodeToken and return its claims Set error if token not valid

func (*JWTIssuer) HandleJWTLogin

func (issuer *JWTIssuer) HandleJWTLogin(resp http.ResponseWriter, req *http.Request)

HandleJWTLogin handles a JWT login POST request. Attach this method to the router with the login route. For example:

> router.HandleFunc("/login", HandleJWTLogin)

The body contains provided userID and password This:

  1. returns a JWT access and refresh token pair
  2. sets a secure, httpOnly, sameSite refresh cookie with the name 'JwtRefreshCookieName'

func (*JWTIssuer) HandleJWTRefresh

func (issuer *JWTIssuer) HandleJWTRefresh(resp http.ResponseWriter, req *http.Request)

HandleJWTRefresh refreshes the access/refresh token pair Attach this method to the router with the refresh route. For example:

> router.HandleFunc("/refresh", HandleJWTRefresh)

This:

  1. Return unauthorized if no valid refresh token was found
  2. returns a JWT access and refresh token pair if the refresh token was valid
  3. sets a secure, httpOnly, sameSite refresh cookie with the name 'JwtRefreshCookieName'

func (*JWTIssuer) WriteJWTTokens

func (issuer *JWTIssuer) WriteJWTTokens(
	accessToken string, refreshToken string, cookieExpTime time.Time, resp http.ResponseWriter) error

WriteJWTTokens writes the access and refresh tokens as response message and in a secure client cookie. The cookieExpTime should be set to the refresh token expiration time.

type JwtClaims

type JwtClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

JwtClaims this is temporary while figuring things out

type TLSServer

type TLSServer struct {
	// contains filtered or unexported fields
}

TLSServer is a simple TLS Server supporting BASIC, Jwt and client certificate authentication

func NewTLSServer

func NewTLSServer(address string, port uint,
	serverCert *tls.Certificate,
	caCert *x509.Certificate,
) *TLSServer

NewTLSServer creates a new TLS Server instance with authentication support. Use AddHandler to handle incoming requests for the given route and indicate if authentication is required.

The following authentication methods are supported:

Certificate based auth using the caCert to verify client certificates
Basic authentication if 'EnableBasicAuth' is used.
JWT asymmetric token authentication if EnableJwtAuth is used.

address        server listening address
port           listening port
serverCert     Server TLS certificate
caCert         CA certificate to verify client certificates

returns TLS server for handling requests

func (*TLSServer) AddHandler

func (srv *TLSServer) AddHandler(path string,
	handler func(userID string, resp http.ResponseWriter, req *http.Request))

AddHandler adds a new handler for a path.

The server authenticates the request before passing it to this handler. The handler's userID is that of the authenticated user, and is intended for authorization of the request. If authentication is not enabled then the userID is empty.

path to listen on. This supports wildcards
handler to invoke with the request. The userID is only provided when an authenticator is used

func (*TLSServer) AddHandlerNoAuth

func (srv *TLSServer) AddHandlerNoAuth(path string,
	handler func(resp http.ResponseWriter, req *http.Request))

AddHandlerNoAuth adds a new handler for a path that does not require authentication The server passes the request directly to the handler

path to listen on. This supports wildcards
handler to invoke with the request. The userID is only provided when an authenticator is used

func (*TLSServer) EnableBasicAuth

func (srv *TLSServer) EnableBasicAuth(validateCredentials func(loginName string, password string) bool)

EnableBasicAuth enables BASIC authentication on this server Basic auth is a legacy authentication scheme and not recommended as it requires each service to have access to the credentials store. Use of JwtAuth is preferred.

validateCredentials is the function that verifies the given credentials

func (*TLSServer) EnableJwtAuth

func (srv *TLSServer) EnableJwtAuth(verificationKey *ecdsa.PublicKey)

EnableJwtAuth enables JWT authentication using asymmetric keys JWT tokens are included in the head authorization field and signed by an issuing authentication server using the server's private key. The provided verification key is the server's public key.

verificationKey is the public key to verify tokens. Use nil to use the server own public key

func (*TLSServer) EnableJwtIssuer

func (srv *TLSServer) EnableJwtIssuer(issuerKey *ecdsa.PrivateKey,
	validateCredentials func(loginName string, password string) bool)

EnableJwtIssuer enables JWT token issuer using asymmetric keys Token are issued using the PUT /login request with payload carrying {username: , password:} Tokens are refreshed using the PUT /refresh request

The login/refresh paths are defined in tlsclient.DefaultJWTLoginPath, tlsclient.DefaultJWTRefreshPath

issuerKey is the private key used to sign the tokens. Use nil to use the server's private key validateCredentials is the handler that matches credentials with those in the credentials store

func (*TLSServer) GetQueryInt

func (srv *TLSServer) GetQueryInt(
	request *http.Request, paramName string, defaultValue int) (value int, err error)

GetQueryInt reads the request query parameter and convert it to an integer

request is the request with the query parameter
paramName is the name of the parameter
defaultValue to use if parameter not provided

Returns an integer value, error if conversion failed (bad request)

func (*TLSServer) GetQueryString

func (srv *TLSServer) GetQueryString(
	request *http.Request, paramName string, defaultValue string) string

GetQueryString reads the request query parameter and returns the first string

request is the request with the query parameter
paramName is the name of the parameter
defaultValue to use if parameter not provided

Returns a single string, with defaultValue if not found

func (*TLSServer) Start

func (srv *TLSServer) Start() error

Start the TLS server using the provided CA and Server certificates. The server will request but not require a client certificate. If one is provided it must be valid.

func (*TLSServer) Stop

func (srv *TLSServer) Stop()

Stop the TLS server and close all connections

func (*TLSServer) WriteBadRequest

func (srv *TLSServer) WriteBadRequest(resp http.ResponseWriter, errMsg string)

WriteBadRequest logs and respond with bad request error status code and log error

func (*TLSServer) WriteForbidden

func (srv *TLSServer) WriteForbidden(resp http.ResponseWriter, errMsg string)

WriteForbidden logs and respond with forbidden (403) code and log http error Use this when access a resource without sufficient credentials

func (*TLSServer) WriteInternalError

func (srv *TLSServer) WriteInternalError(resp http.ResponseWriter, errMsg string)

WriteInternalError logs and responds with internal server error status code and log error

func (*TLSServer) WriteNotFound

func (srv *TLSServer) WriteNotFound(resp http.ResponseWriter, errMsg string)

WriteNotFound logs and respond with 404 resource not found

func (*TLSServer) WriteNotImplemented

func (srv *TLSServer) WriteNotImplemented(resp http.ResponseWriter, errMsg string)

WriteNotImplemented respond with 501 not implemented

func (*TLSServer) WriteUnauthorized

func (srv *TLSServer) WriteUnauthorized(resp http.ResponseWriter, errMsg string)

WriteUnauthorized responds with unauthorized (401) status code and log http error Use this when login fails

Jump to

Keyboard shortcuts

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