mirror of
https://github.com/lightninglabs/aperture.git
synced 2025-12-19 01:54:20 +01:00
auth+proxy: forward auth to backend
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user