debian-forge-composer/internal/auth/jwt_auth_handler.go
Tom Gundersen 0b24099751 jwt: support multiple key providers
We may need to use several SSO providers, so extend our
configuration to allow that.

Based on PoC from Sanne:

```
package main

import (
	"net/http"
	"log"

	"github.com/openshift-online/ocm-sdk-go/authentication"
	"github.com/openshift-online/ocm-sdk-go/logging"
)

type H struct{}

func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Println("HURRAY")
}

func main() {

	logBuilder := logging.NewGoLoggerBuilder()
	logger, err := logBuilder.Build()
	if err != nil {
		panic(err)
	}

	aH, err := authentication.NewHandler().
		KeysURL("https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/certs").
		KeysURL("https://identity.api.openshift.com/auth/realms/rhoas/protocol/openid-connect/certs").
			Logger(logger).Next(&H{}).Build()
	if err != nil {
		panic(err)
	}

	log.Fatal(http.ListenAndServe(":8080", aH))

}
```
2022-01-31 20:40:22 +00:00

70 lines
1.6 KiB
Go

package auth
import (
"context"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
"github.com/openshift-online/ocm-sdk-go/authentication"
"github.com/openshift-online/ocm-sdk-go/logging"
"github.com/osbuild/osbuild-composer/internal/common"
)
// When using this handler for auth, it should be run as high up as possible.
// Exceptions can be registered in the `exclude` slice
func BuildJWTAuthHandler(keysURLs []string, caFile, aclFile string, exclude []string, next http.Handler) (handler http.Handler, err error) {
logBuilder := logging.NewGoLoggerBuilder()
if caFile != "" {
logBuilder = logBuilder.Debug(true)
}
logger, err := logBuilder.Build()
if err != nil {
return
}
logger.Info(context.Background(), aclFile)
builder := authentication.NewHandler().
Logger(logger)
for _, keysURL := range keysURLs {
builder = builder.KeysURL(keysURL)
}
// Used during testing
if caFile != "" {
logger.Warn(context.Background(),
"A custom CA is specified to verify jwt tokens, this shouldn't be enabled in a production setting.")
caPEM, err := ioutil.ReadFile(caFile)
if err != nil {
return nil, err
}
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM(caPEM)
if !ok {
return nil, fmt.Errorf("Unable to load jwt ca cert %s.", caFile)
}
builder = builder.KeysCAs(pool)
}
if aclFile != "" {
builder = builder.ACLFile(aclFile)
}
for _, e := range exclude {
builder = builder.Public(e)
}
// In case authentication fails, attach an OperationID
builder = builder.OperationID(func(r *http.Request) string {
return common.GenerateOperationID()
})
handler, err = builder.Next(next).Build()
return
}