mirror of
https://github.com/nais/wonderwall.git
synced 2026-08-23 21:16:14 +00:00
Revert "refactor: infer redirect URI from configured ingress"
This reverts commit 5f0b0df7cf.
This commit is contained in:
@@ -53,18 +53,19 @@ The following flags are available:
|
||||
|
||||
```shell
|
||||
--auto-login Automatically redirect user to login if the user does not have a valid session for all proxied downstream requests.
|
||||
--bind-address string Listen address for public connections. (default "127.0.0.1:3000")
|
||||
--bind-address string Listen address for public connections. (default "127.0.0.1:8090")
|
||||
--encryption-key string Base64 encoded 256-bit cookie encryption key; must be identical in instances that share session store.
|
||||
--error-redirect-uri string URI to redirect user to on errors for custom error handling.
|
||||
--ingress string Ingress used to access the main application.
|
||||
--ingress string Ingress used to access the main application. (default "/")
|
||||
--log-format string Log format, either 'json' or 'text'. (default "json")
|
||||
--log-level string Logging verbosity level. (default "debug")
|
||||
--metrics-bind-address string Listen address for metrics only. (default "127.0.0.1:3001")
|
||||
--metrics-bind-address string Listen address for metrics only. (default "127.0.0.1:8091")
|
||||
--openid.acr-values string Space separated string that configures the default security level (acr_values) parameter for authorization requests.
|
||||
--openid.client-id string Client ID for the OpenID client.
|
||||
--openid.client-jwk string JWK containing the private key for the OpenID client in string format.
|
||||
--openid.post-logout-redirect-uri string URI for redirecting the user after successful logout at the Identity Provider.
|
||||
--openid.provider string Provider configuration to load and use, either 'openid', 'azure', 'idporten'. (default "openid")
|
||||
--openid.redirect-uri string Redirect URI for the OpenID client that should be used in authorization requests.
|
||||
--openid.scopes strings List of additional scopes (other than 'openid') that should be used during the login flow.
|
||||
--openid.ui-locales string Space-separated string that configures the default UI locale (ui_locales) parameter for OAuth2 consent screen.
|
||||
--openid.well-known-url string URI to the well-known OpenID Configuration metadata document.
|
||||
@@ -80,18 +81,21 @@ At minimum, the following configuration must be provided:
|
||||
|
||||
- `openid.client-id`
|
||||
- `openid.client-jwk`
|
||||
- `openid.redirect-uri`
|
||||
- `openid.well-known-url`
|
||||
- `ingress`
|
||||
|
||||
#### ID-porten
|
||||
|
||||
When the `openid.provider` flag is set to `idporten`, the following environment variables are bound to the required `openid`
|
||||
When the `openid.provider` flag is set to `idporten`, the following environment variables are bound to the required
|
||||
flags described previously:
|
||||
|
||||
- `IDPORTEN_CLIENT_ID`
|
||||
Client ID for the client at ID-porten.
|
||||
- `IDPORTEN_CLIENT_JWK`
|
||||
Private key belonging to the client in JWK format.
|
||||
- `IDPORTEN_REDIRECT_URI`
|
||||
Valid pre-registered redirect URI that ID-porten should redirect the user to as part of the authentication flow.
|
||||
For example: `http://localhost:8090/oauth2/callback`
|
||||
- `IDPORTEN_WELL_KNOWN_URL`
|
||||
Well-known OpenID Configuration endpoint for ID-porten: <https://docs.digdir.no/oidc_func_wellknown.html>.
|
||||
|
||||
@@ -111,6 +115,9 @@ described previously:
|
||||
Client ID for the client at Azure AD.
|
||||
- `AZURE_APP_CLIENT_JWK`
|
||||
Private key belonging to the client in JWK format.
|
||||
- `AZURE_APP_REDIRECT_URI`
|
||||
Valid pre-registered redirect URI that Azure AD should redirect the user to as part of the authentication flow.
|
||||
For example: `http://localhost:8090/oauth2/callback`
|
||||
- `AZURE_APP_WELL_KNOWN_URL`
|
||||
Well-known OpenID Configuration endpoint for Azure AD.
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ type azure struct {
|
||||
func azureFlags() {
|
||||
viper.BindEnv(OpenIDClientID, "AZURE_APP_CLIENT_ID")
|
||||
viper.BindEnv(OpenIDClientJWK, "AZURE_APP_JWK")
|
||||
viper.BindEnv(OpenIDRedirectURI, "AZURE_APP_REDIRECT_URI")
|
||||
viper.BindEnv(OpenIDWellKnownURL, "AZURE_APP_WELL_KNOWN_URL")
|
||||
}
|
||||
|
||||
|
||||
@@ -42,15 +42,15 @@ const (
|
||||
func Initialize() (*Config, error) {
|
||||
conftools.Initialize("wonderwall")
|
||||
|
||||
flag.String(BindAddress, "127.0.0.1:3000", "Listen address for public connections.")
|
||||
flag.String(BindAddress, "127.0.0.1:8090", "Listen address for public connections.")
|
||||
flag.String(LogFormat, "json", "Log format, either 'json' or 'text'.")
|
||||
flag.String(LogLevel, "debug", "Logging verbosity level.")
|
||||
flag.String(MetricsBindAddress, "127.0.0.1:3001", "Listen address for metrics only.")
|
||||
flag.String(MetricsBindAddress, "127.0.0.1:8091", "Listen address for metrics only.")
|
||||
|
||||
flag.Bool(AutoLogin, false, "Automatically redirect user to login if the user does not have a valid session for all proxied downstream requests.")
|
||||
flag.String(EncryptionKey, "", "Base64 encoded 256-bit cookie encryption key; must be identical in instances that share session store.")
|
||||
flag.String(ErrorRedirectURI, "", "URI to redirect user to on errors for custom error handling.")
|
||||
flag.String(Ingress, "", "Ingress used to access the main application.")
|
||||
flag.String(Ingress, "/", "Ingress used to access the main application.")
|
||||
flag.Duration(SessionMaxLifetime, time.Hour, "Max lifetime for user sessions.")
|
||||
flag.String(UpstreamHost, "127.0.0.1:8080", "Address of upstream host.")
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ type idporten struct {
|
||||
func idportenFlags() {
|
||||
viper.BindEnv(OpenIDClientID, "IDPORTEN_CLIENT_ID")
|
||||
viper.BindEnv(OpenIDClientJWK, "IDPORTEN_CLIENT_JWK")
|
||||
viper.BindEnv(OpenIDRedirectURI, "IDPORTEN_REDIRECT_URI")
|
||||
viper.BindEnv(OpenIDWellKnownURL, "IDPORTEN_WELL_KNOWN_URL")
|
||||
|
||||
viper.SetDefault(OpenIDPostLogoutRedirectURI, "https://www.nav.no")
|
||||
|
||||
@@ -12,6 +12,7 @@ const (
|
||||
OpenIDClientID = "openid.client-id"
|
||||
OpenIDClientJWK = "openid.client-jwk"
|
||||
OpenIDPostLogoutRedirectURI = "openid.post-logout-redirect-uri"
|
||||
OpenIDRedirectURI = "openid.redirect-uri"
|
||||
OpenIDScopes = "openid.scopes"
|
||||
OpenIDWellKnownURL = "openid.well-known-url"
|
||||
OpenIDACRValues = "openid.acr-values"
|
||||
@@ -23,6 +24,7 @@ type OpenID struct {
|
||||
ClientID string `json:"client-id"`
|
||||
ClientJWK string `json:"client-jwk"`
|
||||
PostLogoutRedirectURI string `json:"post-logout-redirect-uri"`
|
||||
RedirectURI string `json:"redirect-uri"`
|
||||
Scopes []string `json:"scopes"`
|
||||
WellKnownURL string `json:"well-known-url"`
|
||||
ACRValues string `json:"acr-values"`
|
||||
@@ -39,12 +41,11 @@ const (
|
||||
|
||||
type BaseConfig struct {
|
||||
OpenID
|
||||
clientJwk jwk.Key
|
||||
redirectURI string
|
||||
clientJwk jwk.Key
|
||||
}
|
||||
|
||||
func (in *BaseConfig) GetRedirectURI() string {
|
||||
return in.redirectURI
|
||||
return in.RedirectURI
|
||||
}
|
||||
|
||||
func (in *BaseConfig) GetClientID() string {
|
||||
@@ -75,11 +76,10 @@ func (in *BaseConfig) GetWellKnownURL() string {
|
||||
return in.WellKnownURL
|
||||
}
|
||||
|
||||
func (c *Config) NewBaseConfig(clientJwk jwk.Key, redirectURI string) *BaseConfig {
|
||||
func (c *Config) NewBaseConfig(clientJwk jwk.Key) *BaseConfig {
|
||||
return &BaseConfig{
|
||||
OpenID: c.OpenID,
|
||||
clientJwk: clientJwk,
|
||||
redirectURI: redirectURI,
|
||||
OpenID: c.OpenID,
|
||||
clientJwk: clientJwk,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ func openIDFlags() {
|
||||
flag.String(OpenIDClientID, "", "Client ID for the OpenID client.")
|
||||
flag.String(OpenIDClientJWK, "", "JWK containing the private key for the OpenID client in string format.")
|
||||
flag.String(OpenIDPostLogoutRedirectURI, "", "URI for redirecting the user after successful logout at the Identity Provider.")
|
||||
flag.String(OpenIDRedirectURI, "", "Redirect URI for the OpenID client that should be used in authorization requests.")
|
||||
flag.StringSlice(OpenIDScopes, []string{}, "List of additional scopes (other than 'openid') that should be used during the login flow.")
|
||||
flag.String(OpenIDWellKnownURL, "", "URI to the well-known OpenID Configuration metadata document.")
|
||||
|
||||
|
||||
@@ -3,13 +3,11 @@ package provider
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/lestrrat-go/jwx/jwk"
|
||||
|
||||
"github.com/nais/wonderwall/pkg/config"
|
||||
"github.com/nais/wonderwall/pkg/openid"
|
||||
"github.com/nais/wonderwall/pkg/router/paths"
|
||||
)
|
||||
|
||||
type Provider interface {
|
||||
@@ -47,17 +45,7 @@ func NewProvider(cfg *config.Config) (Provider, error) {
|
||||
return nil, fmt.Errorf("parsing client JWK: %w", err)
|
||||
}
|
||||
|
||||
ingress := cfg.Ingress
|
||||
if len(ingress) == 0 {
|
||||
return nil, fmt.Errorf("missing required config %s", config.Ingress)
|
||||
}
|
||||
|
||||
redirectURI, err := redirectURI(ingress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating redirect URI from ingress: %w", err)
|
||||
}
|
||||
|
||||
baseConfig := cfg.NewBaseConfig(clientJwk, redirectURI)
|
||||
baseConfig := cfg.NewBaseConfig(clientJwk)
|
||||
var clientConfig openid.ClientConfiguration
|
||||
switch cfg.OpenID.Provider {
|
||||
case config.ProviderIDPorten:
|
||||
@@ -78,6 +66,10 @@ func NewProvider(cfg *config.Config) (Provider, error) {
|
||||
return nil, fmt.Errorf("missing required config %s", config.OpenIDWellKnownURL)
|
||||
}
|
||||
|
||||
if len(clientConfig.GetRedirectURI()) == 0 {
|
||||
return nil, fmt.Errorf("missing required config %s", config.OpenIDRedirectURI)
|
||||
}
|
||||
|
||||
configuration, err := openid.FetchWellKnownConfig(clientConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetching well known config: %w", err)
|
||||
@@ -104,17 +96,3 @@ func NewProvider(cfg *config.Config) (Provider, error) {
|
||||
jwkSet: jwkSet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func redirectURI(ingress string) (string, error) {
|
||||
base, err := url.Parse(ingress)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
callbackPath, err := url.Parse(paths.OAuth2 + paths.Callback)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return base.ResolveReference(callbackPath).String(), nil
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/nais/wonderwall/pkg/config"
|
||||
"github.com/nais/wonderwall/pkg/cookie"
|
||||
"github.com/nais/wonderwall/pkg/openid"
|
||||
"github.com/nais/wonderwall/pkg/router/paths"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -85,7 +84,7 @@ func RetryURI(r *http.Request, ingress string, loginCookie *cookie.Login) string
|
||||
|
||||
prefix := config.ParseIngress(ingress)
|
||||
|
||||
if strings.HasSuffix(retryURI, paths.OAuth2+paths.Logout) || strings.HasSuffix(retryURI, paths.OAuth2+paths.FrontChannelLogout) {
|
||||
if strings.HasSuffix(retryURI, "/oauth2/logout") || strings.HasSuffix(retryURI, "/oauth2/logout/frontchannel") {
|
||||
return prefix + retryURI
|
||||
}
|
||||
|
||||
@@ -114,7 +113,7 @@ func RetryURI(r *http.Request, ingress string, loginCookie *cookie.Login) string
|
||||
redirect = loginCookie.Referer
|
||||
}
|
||||
|
||||
retryURI = fmt.Sprintf(prefix + paths.OAuth2 + paths.Login)
|
||||
retryURI = fmt.Sprintf("%s/oauth2/login", prefix)
|
||||
retryURI = retryURI + fmt.Sprintf("?%s=%s", RedirectURLParameter, redirect)
|
||||
return retryURI
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package paths
|
||||
|
||||
const (
|
||||
OAuth2 = "/oauth2"
|
||||
Login = "/login"
|
||||
Callback = "/callback"
|
||||
Logout = "/logout"
|
||||
FrontChannelLogout = "/logout/frontchannel"
|
||||
)
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/nais/wonderwall/pkg/config"
|
||||
"github.com/nais/wonderwall/pkg/middleware"
|
||||
"github.com/nais/wonderwall/pkg/router/paths"
|
||||
)
|
||||
|
||||
func New(handler *Handler) chi.Router {
|
||||
@@ -17,14 +16,14 @@ func New(handler *Handler) chi.Router {
|
||||
|
||||
prefix := config.ParseIngress(handler.Config.Ingress)
|
||||
|
||||
r.Route(prefix+paths.OAuth2, func(r chi.Router) {
|
||||
r.Route(prefix+"/oauth2", func(r chi.Router) {
|
||||
r.Use(middleware.LogEntryHandler(handler.httplogger))
|
||||
r.Use(prometheusMiddleware.Handler)
|
||||
r.Use(chi_middleware.NoCache)
|
||||
r.Get(paths.Login, handler.Login)
|
||||
r.Get(paths.Callback, handler.Callback)
|
||||
r.Get(paths.Logout, handler.Logout)
|
||||
r.Get(paths.FrontChannelLogout, handler.FrontChannelLogout)
|
||||
r.Get("/login", handler.Login)
|
||||
r.Get("/callback", handler.Callback)
|
||||
r.Get("/logout", handler.Logout)
|
||||
r.Get("/logout/frontchannel", handler.FrontChannelLogout)
|
||||
})
|
||||
r.HandleFunc("/*", handler.Default)
|
||||
return r
|
||||
|
||||
Reference in New Issue
Block a user