auth+proxy: forward auth to backend

This commit is contained in:
Oliver Gugger
2019-11-15 16:58:19 +01:00
parent 8f4dfc5d57
commit aef413da0a
2 changed files with 35 additions and 8 deletions

View File

@@ -29,6 +29,7 @@ const (
var ( var (
authRegex = regexp.MustCompile("LSAT (.*?):([a-f0-9]{64})") authRegex = regexp.MustCompile("LSAT (.*?):([a-f0-9]{64})")
authFormat = "LSAT %s:%s"
opWildcard = "*" opWildcard = "*"
) )
@@ -65,7 +66,7 @@ func (l *LsatAuthenticator) Accept(header *http.Header) bool {
// Try reading the macaroon and preimage from the HTTP header. This can // Try reading the macaroon and preimage from the HTTP header. This can
// be in different header fields depending on the implementation and/or // be in different header fields depending on the implementation and/or
// protocol. // protocol.
mac, preimageBytes, err := authFromHeader(header) mac, preimageBytes, err := FromHeader(header)
if err != nil { if err != nil {
log.Debugf("Deny: %v", err) log.Debugf("Deny: %v", err)
return false return false
@@ -125,7 +126,7 @@ func (l *LsatAuthenticator) FreshChallengeHeader(r *http.Request) (
return header, nil return header, nil
} }
// authFromHeader tries to extract authentication information from HTTP headers. // FromHeader tries to extract authentication information from HTTP headers.
// There are two supported formats that can be sent in three different header // There are two supported formats that can be sent in three different header
// fields: // fields:
// 1. Authorization: LSAT <macBase64>:<preimageHex> // 1. Authorization: LSAT <macBase64>:<preimageHex>
@@ -133,7 +134,7 @@ func (l *LsatAuthenticator) FreshChallengeHeader(r *http.Request) (
// 3. Macaroon: <macHex> // 3. Macaroon: <macHex>
// If only the macaroon is sent in header 2 or three then it is expected to have // If only the macaroon is sent in header 2 or three then it is expected to have
// a caveat with the preimage attached to it. // a caveat with the preimage attached to it.
func authFromHeader(header *http.Header) (*macaroon.Macaroon, []byte, error) { func FromHeader(header *http.Header) (*macaroon.Macaroon, []byte, error) {
var authHeader string var authHeader string
switch { switch {
@@ -165,7 +166,7 @@ func authFromHeader(header *http.Header) (*macaroon.Macaroon, []byte, error) {
mac := &macaroon.Macaroon{} mac := &macaroon.Macaroon{}
err = mac.UnmarshalBinary(macBytes) err = mac.UnmarshalBinary(macBytes)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to unmarshal " + return nil, nil, fmt.Errorf("unable to unmarshal "+
"macaroon: %v", err) "macaroon: %v", err)
} }
preimageBytes, err := hex.DecodeString(preimageHex) preimageBytes, err := hex.DecodeString(preimageHex)
@@ -216,3 +217,20 @@ func authFromHeader(header *http.Header) (*macaroon.Macaroon, []byte, error) {
return mac, preimageBytes, nil return mac, preimageBytes, nil
} }
// SetHeader sets the provided authentication elements as the default/standard
// HTTP header for the LSAT protocol.
func SetHeader(header *http.Header, mac *macaroon.Macaroon,
preimage []byte) error {
macBytes, err := mac.MarshalBinary()
if err != nil {
return err
}
value := fmt.Sprintf(
authFormat, base64.StdEncoding.EncodeToString(macBytes),
hex.EncodeToString(preimage),
)
header.Set(HeaderAuthorization, value)
return nil
}

View File

@@ -19,7 +19,7 @@ const (
// formatPattern is the pattern in which the request log will be // formatPattern is the pattern in which the request log will be
// printed. This is loosely oriented on the apache log format. // printed. This is loosely oriented on the apache log format.
// An example entry would look like this: // An example entry would look like this:
// 2019-11-09 04:07:55.072 [INF] PRXY: 66.249.69.89 - - // 2019-11-09 04:07:55.072 [INF] PRXY: 66.249.69.89 - -
// "GET /availability/v1/btc.json HTTP/1.1" "" "Mozilla/5.0 ..." // "GET /availability/v1/btc.json HTTP/1.1" "" "Mozilla/5.0 ..."
formatPattern = "- - \"%s %s %s\" \"%s\" \"%s\"" formatPattern = "- - \"%s %s %s\" \"%s\" \"%s\""
hdrContentType = "Content-Type" hdrContentType = "Content-Type"
@@ -181,9 +181,18 @@ func (p *Proxy) director(req *http.Request) {
req.URL.Host = target.Address req.URL.Host = target.Address
req.URL.Scheme = target.Protocol req.URL.Scheme = target.Protocol
// Don't forward the authorization header since the // Make sure we always forward the authorization in the correct/
// services won't know what it is. // default format so the backend knows what to do with it.
req.Header.Del("Authorization") mac, preimage, err := auth.FromHeader(&req.Header)
if err == nil {
// It could be that there is no auth information because
// none is needed for this particular request. So we
// only continue if no error is set.
err := auth.SetHeader(&req.Header, mac, preimage)
if err != nil {
log.Errorf("could not set header: %v", err)
}
}
// Now overwrite header fields of the client request // Now overwrite header fields of the client request
// with the fields from the configuration file. // with the fields from the configuration file.