From 8378bc9958c69c3480e8bac42b32464cad7cfdae Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 16 Nov 2021 18:40:39 -0800 Subject: [PATCH] support dynamic redirect_uri based on incoming 'host' header (#13666) This feature is useful in situations when console is exposed over multiple intranent or internet entities when users are connecting over local IP v/s going through load balancer. Related console work was merged here https://github.com/minio/console/commit/373bfbfe3f16e6f7d376fb9765a4610d76cf15a2 --- cmd/common-main.go | 7 ++- go.mod | 4 +- go.sum | 9 ++-- internal/config/identity/openid/help.go | 30 ++++++----- internal/config/identity/openid/jwt.go | 68 ++++++++++++++----------- 5 files changed, 68 insertions(+), 50 deletions(-) diff --git a/cmd/common-main.go b/cmd/common-main.go index d7638ce77..fb22f7701 100644 --- a/cmd/common-main.go +++ b/cmd/common-main.go @@ -174,7 +174,12 @@ func minioConfigToConsoleFeatures() { os.Setenv("CONSOLE_IDP_HMAC_PASSPHRASE", globalOpenIDConfig.ClientID) os.Setenv("CONSOLE_IDP_SCOPES", strings.Join(globalOpenIDConfig.DiscoveryDoc.ScopesSupported, ",")) if globalOpenIDConfig.ClaimUserinfo { - os.Setenv("CONSOLE_IDP_USERINFO", "on") + os.Setenv("CONSOLE_IDP_USERINFO", config.EnableOn) + } + if globalOpenIDConfig.RedirectURIDynamic { + // Enable dynamic redirect-uri's based on incoming 'host' header, + // Overrides any other callback URL. + os.Setenv("CONSOLE_IDP_CALLBACK_DYNAMIC", config.EnableOn) } if globalOpenIDConfig.RedirectURI != "" { os.Setenv("CONSOLE_IDP_CALLBACK", globalOpenIDConfig.RedirectURI) diff --git a/go.mod b/go.mod index 218698c1d..54b4a761b 100644 --- a/go.mod +++ b/go.mod @@ -44,14 +44,14 @@ require ( github.com/lib/pq v1.9.0 github.com/miekg/dns v1.1.43 github.com/minio/cli v1.22.0 - github.com/minio/console v0.12.3 + github.com/minio/console v0.12.4-0.20211116014825-f5234d283099 github.com/minio/csvparser v1.0.0 github.com/minio/highwayhash v1.0.2 github.com/minio/kes v0.14.0 github.com/minio/madmin-go v1.1.12 github.com/minio/minio-go/v7 v7.0.15 github.com/minio/parquet-go v1.1.0 - github.com/minio/pkg v1.1.6 + github.com/minio/pkg v1.1.7 github.com/minio/selfupdate v0.3.1 github.com/minio/sha256-simd v1.0.0 github.com/minio/simdjson-go v0.2.1 diff --git a/go.sum b/go.sum index 614552783..44b866420 100644 --- a/go.sum +++ b/go.sum @@ -1069,8 +1069,8 @@ github.com/minio/cli v1.22.0 h1:VTQm7lmXm3quxO917X3p+el1l0Ca5X3S4PM2ruUYO68= github.com/minio/cli v1.22.0/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY= github.com/minio/colorjson v1.0.1 h1:+hvfP8C1iMB95AT+ZFDRE+Knn9QPd9lg0CRJY9DRpos= github.com/minio/colorjson v1.0.1/go.mod h1:oPM3zQQY8Gz9NGtgvuBEjQ+gPZLKAGc7T+kjMlwtOgs= -github.com/minio/console v0.12.3 h1:YJbe0FVSrvZKu26a3/1qYUvznH1pqc1nWlOabGAXUPQ= -github.com/minio/console v0.12.3/go.mod h1:tPtNL+4dcb/2sJkNNNusGi4mSnfsgzQzRUZa5QD7dTo= +github.com/minio/console v0.12.4-0.20211116014825-f5234d283099 h1:9Sh/Su9RZDUO97lGEh3glw5aVyhvQY7EZGVhGHoy7lI= +github.com/minio/console v0.12.4-0.20211116014825-f5234d283099/go.mod h1:byf3D60Fe3/5oVrypMCXd/CkJcADc3b4C/a8Sj7AgNE= github.com/minio/csvparser v1.0.0 h1:xJEHcYK8ZAjeW4hNV9Zu30u+/2o4UyPnYgyjWp8b7ZU= github.com/minio/csvparser v1.0.0/go.mod h1:lKXskSLzPgC5WQyzP7maKH7Sl1cqvANXo9YCto8zbtM= github.com/minio/direct-csi v1.3.5-0.20210601185811-f7776f7961bf h1:wylCc/PdvdTIqYqVNEU9LJAZBanvfGY1TwTnjM3zQaA= @@ -1107,9 +1107,8 @@ github.com/minio/pkg v1.0.3/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8= github.com/minio/pkg v1.0.11/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= github.com/minio/pkg v1.1.3/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= -github.com/minio/pkg v1.1.5/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= -github.com/minio/pkg v1.1.6 h1:rCVrsniDzb031SRwSXtxxJQPntItQR02IXYgM6CirOw= -github.com/minio/pkg v1.1.6/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= +github.com/minio/pkg v1.1.7 h1:v+2/ol/h1Sl0iJdOFN1Srk4CzksMIDsfugXCZYb5L7Y= +github.com/minio/pkg v1.1.7/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs= github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= diff --git a/internal/config/identity/openid/help.go b/internal/config/identity/openid/help.go index 134816d18..b8f7be9d2 100644 --- a/internal/config/identity/openid/help.go +++ b/internal/config/identity/openid/help.go @@ -50,18 +50,6 @@ var ( Optional: true, Type: "on|off", }, - config.HelpKV{ - Key: ClaimPrefix, - Description: `[DEPRECATED use 'claim_name'] JWT claim namespace prefix e.g. "customer1/"`, - Optional: true, - Type: "string", - }, - config.HelpKV{ - Key: RedirectURI, - Description: `[DEPRECATED use env 'MINIO_BROWSER_REDIRECT_URL'] Configure custom redirect_uri for OpenID login flow callback`, - Optional: true, - Type: "string", - }, config.HelpKV{ Key: Scopes, Description: `Comma separated list of OpenID scopes for server, defaults to advertised scopes from discovery document e.g. "email,admin"`, @@ -86,6 +74,24 @@ var ( Optional: true, Type: "string", }, + config.HelpKV{ + Key: RedirectURIDynamic, + Description: `Enable 'Host' header based dynamic redirect URI`, + Optional: true, + Type: "on|off", + }, + config.HelpKV{ + Key: ClaimPrefix, + Description: `[DEPRECATED use 'claim_name'] JWT claim namespace prefix e.g. "customer1/"`, + Optional: true, + Type: "string", + }, + config.HelpKV{ + Key: RedirectURI, + Description: `[DEPRECATED use env 'MINIO_BROWSER_REDIRECT_URL'] Configure custom redirect_uri for OpenID login flow callback`, + Optional: true, + Type: "string", + }, config.HelpKV{ Key: config.Comment, Description: config.DefaultComment, diff --git a/internal/config/identity/openid/jwt.go b/internal/config/identity/openid/jwt.go index 88fd62746..a1c57cbd6 100644 --- a/internal/config/identity/openid/jwt.go +++ b/internal/config/identity/openid/jwt.go @@ -47,14 +47,15 @@ type Config struct { JWKS struct { URL *xnet.URL `json:"url"` } `json:"jwks"` - URL *xnet.URL `json:"url,omitempty"` - ClaimPrefix string `json:"claimPrefix,omitempty"` - ClaimName string `json:"claimName,omitempty"` - ClaimUserinfo bool `json:"claimUserInfo,omitempty"` - RedirectURI string `json:"redirectURI,omitempty"` - DiscoveryDoc DiscoveryDoc - ClientID string - ClientSecret string + URL *xnet.URL `json:"url,omitempty"` + ClaimPrefix string `json:"claimPrefix,omitempty"` + ClaimName string `json:"claimName,omitempty"` + ClaimUserinfo bool `json:"claimUserInfo,omitempty"` + RedirectURI string `json:"redirectURI,omitempty"` + RedirectURIDynamic bool `json:"redirectURIDynamic"` + DiscoveryDoc DiscoveryDoc + ClientID string + ClientSecret string provider provider.Provider publicKeys map[string]crypto.PublicKey @@ -366,23 +367,25 @@ const ( ClientID = "client_id" ClientSecret = "client_secret" - Vendor = "vendor" - Scopes = "scopes" - RedirectURI = "redirect_uri" + Vendor = "vendor" + Scopes = "scopes" + RedirectURI = "redirect_uri" + RedirectURIDynamic = "redirect_uri_dynamic" // Vendor specific ENV only enabled if the Vendor matches == "vendor" KeyCloakRealm = "keycloak_realm" KeyCloakAdminURL = "keycloak_admin_url" - EnvIdentityOpenIDVendor = "MINIO_IDENTITY_OPENID_VENDOR" - EnvIdentityOpenIDClientID = "MINIO_IDENTITY_OPENID_CLIENT_ID" - EnvIdentityOpenIDClientSecret = "MINIO_IDENTITY_OPENID_CLIENT_SECRET" - EnvIdentityOpenIDURL = "MINIO_IDENTITY_OPENID_CONFIG_URL" - EnvIdentityOpenIDClaimName = "MINIO_IDENTITY_OPENID_CLAIM_NAME" - EnvIdentityOpenIDClaimUserInfo = "MINIO_IDENTITY_OPENID_CLAIM_USERINFO" - EnvIdentityOpenIDClaimPrefix = "MINIO_IDENTITY_OPENID_CLAIM_PREFIX" - EnvIdentityOpenIDRedirectURI = "MINIO_IDENTITY_OPENID_REDIRECT_URI" - EnvIdentityOpenIDScopes = "MINIO_IDENTITY_OPENID_SCOPES" + EnvIdentityOpenIDVendor = "MINIO_IDENTITY_OPENID_VENDOR" + EnvIdentityOpenIDClientID = "MINIO_IDENTITY_OPENID_CLIENT_ID" + EnvIdentityOpenIDClientSecret = "MINIO_IDENTITY_OPENID_CLIENT_SECRET" + EnvIdentityOpenIDURL = "MINIO_IDENTITY_OPENID_CONFIG_URL" + EnvIdentityOpenIDClaimName = "MINIO_IDENTITY_OPENID_CLAIM_NAME" + EnvIdentityOpenIDClaimUserInfo = "MINIO_IDENTITY_OPENID_CLAIM_USERINFO" + EnvIdentityOpenIDClaimPrefix = "MINIO_IDENTITY_OPENID_CLAIM_PREFIX" + EnvIdentityOpenIDRedirectURI = "MINIO_IDENTITY_OPENID_REDIRECT_URI" + EnvIdentityOpenIDRedirectURIDynamic = "MINIO_IDENTITY_OPENID_REDIRECT_URI_DYNAMIC" + EnvIdentityOpenIDScopes = "MINIO_IDENTITY_OPENID_SCOPES" // Vendor specific ENVs only enabled if the Vendor matches == "vendor" EnvIdentityOpenIDKeyCloakRealm = "MINIO_IDENTITY_OPENID_KEYCLOAK_REALM" @@ -463,6 +466,10 @@ var ( Key: RedirectURI, Value: "", }, + config.KV{ + Key: RedirectURIDynamic, + Value: "off", + }, config.KV{ Key: Scopes, Value: "", @@ -485,16 +492,17 @@ func LookupConfig(kvs config.KVS, transport *http.Transport, closeRespFn func(io } c = Config{ - RWMutex: &sync.RWMutex{}, - ClaimName: env.Get(EnvIdentityOpenIDClaimName, kvs.Get(ClaimName)), - ClaimUserinfo: env.Get(EnvIdentityOpenIDClaimUserInfo, kvs.Get(ClaimUserinfo)) == config.EnableOn, - ClaimPrefix: env.Get(EnvIdentityOpenIDClaimPrefix, kvs.Get(ClaimPrefix)), - RedirectURI: env.Get(EnvIdentityOpenIDRedirectURI, kvs.Get(RedirectURI)), - publicKeys: make(map[string]crypto.PublicKey), - ClientID: env.Get(EnvIdentityOpenIDClientID, kvs.Get(ClientID)), - ClientSecret: env.Get(EnvIdentityOpenIDClientSecret, kvs.Get(ClientSecret)), - transport: transport, - closeRespFn: closeRespFn, + RWMutex: &sync.RWMutex{}, + ClaimName: env.Get(EnvIdentityOpenIDClaimName, kvs.Get(ClaimName)), + ClaimUserinfo: env.Get(EnvIdentityOpenIDClaimUserInfo, kvs.Get(ClaimUserinfo)) == config.EnableOn, + ClaimPrefix: env.Get(EnvIdentityOpenIDClaimPrefix, kvs.Get(ClaimPrefix)), + RedirectURI: env.Get(EnvIdentityOpenIDRedirectURI, kvs.Get(RedirectURI)), + RedirectURIDynamic: env.Get(EnvIdentityOpenIDRedirectURIDynamic, kvs.Get(RedirectURIDynamic)) == config.EnableOn, + publicKeys: make(map[string]crypto.PublicKey), + ClientID: env.Get(EnvIdentityOpenIDClientID, kvs.Get(ClientID)), + ClientSecret: env.Get(EnvIdentityOpenIDClientSecret, kvs.Get(ClientSecret)), + transport: transport, + closeRespFn: closeRespFn, } configURL := env.Get(EnvIdentityOpenIDURL, kvs.Get(ConfigURL))