root: fix config loading for outposts (#6640)
* root: fix config loading for outposts Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix error handling Signed-off-by: Jens Langhammer <jens@goauthentik.io> * improve check to see if outpost is embedded or not Signed-off-by: Jens Langhammer <jens@goauthentik.io> * also fix oauth url fetching Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
04f46c1d18
commit
9e29789c09
|
@ -0,0 +1,10 @@
|
||||||
|
package lib
|
||||||
|
|
||||||
|
import _ "embed"
|
||||||
|
|
||||||
|
//go:embed default.yml
|
||||||
|
var defaultConfig []byte
|
||||||
|
|
||||||
|
func DefaultConfig() []byte {
|
||||||
|
return defaultConfig
|
||||||
|
}
|
|
@ -62,7 +62,8 @@ class OAuthSourceSerializer(SourceSerializer):
|
||||||
well_known_config = session.get(well_known)
|
well_known_config = session.get(well_known)
|
||||||
well_known_config.raise_for_status()
|
well_known_config.raise_for_status()
|
||||||
except RequestException as exc:
|
except RequestException as exc:
|
||||||
raise ValidationError(exc.response.text)
|
text = exc.response.text if exc.response else str(exc)
|
||||||
|
raise ValidationError(text)
|
||||||
config = well_known_config.json()
|
config = well_known_config.json()
|
||||||
try:
|
try:
|
||||||
attrs["authorization_url"] = config["authorization_endpoint"]
|
attrs["authorization_url"] = config["authorization_endpoint"]
|
||||||
|
@ -78,7 +79,8 @@ class OAuthSourceSerializer(SourceSerializer):
|
||||||
jwks_config = session.get(jwks_url)
|
jwks_config = session.get(jwks_url)
|
||||||
jwks_config.raise_for_status()
|
jwks_config.raise_for_status()
|
||||||
except RequestException as exc:
|
except RequestException as exc:
|
||||||
raise ValidationError(exc.response.text)
|
text = exc.response.text if exc.response else str(exc)
|
||||||
|
raise ValidationError(text)
|
||||||
config = jwks_config.json()
|
config = jwks_config.json()
|
||||||
attrs["oidc_jwks"] = config
|
attrs["oidc_jwks"] = config
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -11,13 +12,16 @@ import (
|
||||||
|
|
||||||
env "github.com/Netflix/go-env"
|
env "github.com/Netflix/go-env"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"goauthentik.io/authentik/lib"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cfg *Config
|
var cfg *Config
|
||||||
|
|
||||||
|
const defaultConfigPath = "./authentik/lib/default.yml"
|
||||||
|
|
||||||
func getConfigPaths() []string {
|
func getConfigPaths() []string {
|
||||||
configPaths := []string{"./authentik/lib/default.yml", "/etc/authentik/config.yml", ""}
|
configPaths := []string{defaultConfigPath, "/etc/authentik/config.yml", ""}
|
||||||
globConfigPaths, _ := filepath.Glob("/etc/authentik/config.d/*.yml")
|
globConfigPaths, _ := filepath.Glob("/etc/authentik/config.d/*.yml")
|
||||||
configPaths = append(configPaths, globConfigPaths...)
|
configPaths = append(configPaths, globConfigPaths...)
|
||||||
|
|
||||||
|
@ -63,20 +67,36 @@ func Get() *Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Setup(paths ...string) {
|
func (c *Config) Setup(paths ...string) {
|
||||||
|
// initially try to load the default config which is compiled in
|
||||||
|
err := c.LoadConfig(lib.DefaultConfig())
|
||||||
|
// this should never fail
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("failed to load inbuilt config: %v", err))
|
||||||
|
}
|
||||||
|
log.WithField("path", "inbuilt-default").Debug("Loaded config")
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
err := c.LoadConfig(path)
|
err := c.LoadConfigFromFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Info("failed to load config, skipping")
|
log.WithError(err).Info("failed to load config, skipping")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := c.fromEnv()
|
err = c.fromEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Info("failed to load env vars")
|
log.WithError(err).Info("failed to load env vars")
|
||||||
}
|
}
|
||||||
c.configureLogger()
|
c.configureLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) LoadConfig(path string) error {
|
func (c *Config) LoadConfig(raw []byte) error {
|
||||||
|
err := yaml.Unmarshal(raw, c)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse YAML: %w", err)
|
||||||
|
}
|
||||||
|
c.walkScheme(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) LoadConfigFromFile(path string) error {
|
||||||
raw, err := os.ReadFile(path)
|
raw, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
@ -84,11 +104,10 @@ func (c *Config) LoadConfig(path string) error {
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to load config file: %w", err)
|
return fmt.Errorf("failed to load config file: %w", err)
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal(raw, c)
|
err = c.LoadConfig(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse YAML: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
c.walkScheme(c)
|
|
||||||
log.WithField("path", path).Debug("Loaded config")
|
log.WithField("path", path).Debug("Loaded config")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ type Application struct {
|
||||||
|
|
||||||
errorTemplates *template.Template
|
errorTemplates *template.Template
|
||||||
authHeaderCache *ttlcache.Cache[string, Claims]
|
authHeaderCache *ttlcache.Cache[string, Claims]
|
||||||
|
|
||||||
|
isEmbedded bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server interface {
|
type Server interface {
|
||||||
|
@ -86,15 +88,15 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server) (*A
|
||||||
CallbackSignature: []string{"true"},
|
CallbackSignature: []string{"true"},
|
||||||
}.Encode()
|
}.Encode()
|
||||||
|
|
||||||
managed := false
|
isEmbedded := false
|
||||||
if m := server.API().Outpost.Managed.Get(); m != nil {
|
if m := server.API().Outpost.Managed.Get(); m != nil {
|
||||||
managed = *m == "goauthentik.io/outposts/embedded"
|
isEmbedded = *m == "goauthentik.io/outposts/embedded"
|
||||||
}
|
}
|
||||||
// Configure an OpenID Connect aware OAuth2 client.
|
// Configure an OpenID Connect aware OAuth2 client.
|
||||||
endpoint := GetOIDCEndpoint(
|
endpoint := GetOIDCEndpoint(
|
||||||
p,
|
p,
|
||||||
server.API().Outpost.Config["authentik_host"].(string),
|
server.API().Outpost.Config["authentik_host"].(string),
|
||||||
managed,
|
isEmbedded,
|
||||||
)
|
)
|
||||||
|
|
||||||
verifier := oidc.NewVerifier(endpoint.Issuer, ks, &oidc.Config{
|
verifier := oidc.NewVerifier(endpoint.Issuer, ks, &oidc.Config{
|
||||||
|
@ -132,6 +134,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server) (*A
|
||||||
ak: server.API(),
|
ak: server.API(),
|
||||||
authHeaderCache: ttlcache.New(ttlcache.WithDisableTouchOnHit[string, Claims]()),
|
authHeaderCache: ttlcache.New(ttlcache.WithDisableTouchOnHit[string, Claims]()),
|
||||||
srv: server,
|
srv: server,
|
||||||
|
isEmbedded: isEmbedded,
|
||||||
}
|
}
|
||||||
go a.authHeaderCache.Start()
|
go a.authHeaderCache.Start()
|
||||||
a.sessions = a.getStore(p, externalHost)
|
a.sessions = a.getStore(p, externalHost)
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL)
|
||||||
// Add one to the validity to ensure we don't have a session with indefinite length
|
// Add one to the validity to ensure we don't have a session with indefinite length
|
||||||
maxAge = int(*t) + 1
|
maxAge = int(*t) + 1
|
||||||
}
|
}
|
||||||
if config.Get().Redis.Host != "" {
|
if a.isEmbedded {
|
||||||
rs, err := redistore.NewRediStoreWithDB(10, "tcp", fmt.Sprintf("%s:%d", config.Get().Redis.Host, config.Get().Redis.Port), config.Get().Redis.Password, strconv.Itoa(config.Get().Redis.DB))
|
rs, err := redistore.NewRediStoreWithDB(10, "tcp", fmt.Sprintf("%s:%d", config.Get().Redis.Host, config.Get().Redis.Port), config.Get().Redis.Password, strconv.Itoa(config.Get().Redis.DB))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
Reference in New Issue