Skip to content

Commit 7b4254f

Browse files
authored
Display errors during IDP authentication (#685)
1 parent 68ea3b5 commit 7b4254f

File tree

12 files changed

+87
-42
lines changed

12 files changed

+87
-42
lines changed

pkg/auth/idp/oauth2/config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,13 @@ var defaultSaltForIdpHmac = utils.RandomCharString(64)
6666
func getSaltForIdpHmac() string {
6767
return env.Get(ConsoleIdpHmacSalt, defaultSaltForIdpHmac)
6868
}
69+
70+
// getIdpScopes return default scopes during the IDP login request
71+
func getIdpScopes() string {
72+
return env.Get(ConsoleIDPScopes, "openid,profile,app_metadata,user_metadata,email")
73+
}
74+
75+
// getIdpTokenExpiration return default token expiration for access token (in seconds)
76+
func getIdpTokenExpiration() string {
77+
return env.Get(ConsoleIDPTokenExpiration, "3600")
78+
}

pkg/auth/idp/oauth2/const.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ package oauth2
1818

1919
const (
2020
// const for idp configuration
21-
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
22-
ConsoleIdpURL = "CONSOLE_IDP_URL"
23-
ConsoleIdpClientID = "CONSOLE_IDP_CLIENT_ID"
24-
ConsoleIdpSecret = "CONSOLE_IDP_SECRET"
25-
ConsoleIdpCallbackURL = "CONSOLE_IDP_CALLBACK"
26-
ConsoleIdpHmacPassphrase = "CONSOLE_IDP_HMAC_PASSPHRASE"
27-
ConsoleIdpHmacSalt = "CONSOLE_IDP_HMAC_SALT"
21+
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
22+
ConsoleIdpURL = "CONSOLE_IDP_URL"
23+
ConsoleIdpClientID = "CONSOLE_IDP_CLIENT_ID"
24+
ConsoleIdpSecret = "CONSOLE_IDP_SECRET"
25+
ConsoleIdpCallbackURL = "CONSOLE_IDP_CALLBACK"
26+
ConsoleIdpHmacPassphrase = "CONSOLE_IDP_HMAC_PASSPHRASE"
27+
ConsoleIdpHmacSalt = "CONSOLE_IDP_HMAC_SALT"
28+
ConsoleIDPScopes = "CONSOLE_IDP_SCOPES"
29+
ConsoleIDPTokenExpiration = "CONSOLE_IDP_TOKEN_EXPIRATION"
2830
)

pkg/auth/idp/oauth2/provider.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"log"
2626
"net/http"
2727
"net/url"
28+
"strconv"
2829
"strings"
2930
"time"
3031

@@ -115,12 +116,14 @@ func NewOauth2ProviderClient(ctx context.Context, scopes []string, httpClient *h
115116
if err != nil {
116117
return nil, err
117118
}
119+
// below verification should not be necessary if the user configure exactly the
120+
// scopes he need, will be removed on a future release
118121
if u.Host == "google.com" {
119122
scopes = []string{oidc.ScopeOpenID}
120123
}
121-
// If provided scopes are empty we use a default list
124+
// If provided scopes are empty we use a default list or the user configured list
122125
if len(scopes) == 0 {
123-
scopes = []string{oidc.ScopeOpenID, "profile", "app_metadata", "user_metadata", "email"}
126+
scopes = strings.Split(getIdpScopes(), ",")
124127
}
125128
client := new(Provider)
126129
client.oauth2Config = &xoauth2.Config{
@@ -177,9 +180,22 @@ func (client *Provider) VerifyIdentity(ctx context.Context, code, state string)
177180
return nil, errors.New("invalid token")
178181
}
179182

183+
// expiration configured in the token itself
184+
expiration := int(oauth2Token.Expiry.Sub(time.Now().UTC()).Seconds())
185+
186+
// check if user configured a hardcoded expiration for console via env variables
187+
// and override the incoming expiration
188+
userConfiguredExpiration := getIdpTokenExpiration()
189+
if userConfiguredExpiration != "" {
190+
expiration, _ = strconv.Atoi(userConfiguredExpiration)
191+
}
192+
idToken := oauth2Token.Extra("id_token")
193+
if idToken == nil {
194+
return nil, errors.New("returned token is missing id_token claim")
195+
}
180196
return &credentials.WebIdentityToken{
181-
Token: oauth2Token.Extra("id_token").(string),
182-
Expiry: int(oauth2Token.Expiry.Sub(time.Now().UTC()).Seconds()),
197+
Token: idToken.(string),
198+
Expiry: expiration,
183199
}, nil
184200
}
185201
stsEndpoint := GetSTSEndpoint()
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
{
22
"files": {
33
"main.css": "/static/css/main.a19f3d53.chunk.css",
4-
"main.js": "/static/js/main.92bfa60e.chunk.js",
5-
"main.js.map": "/static/js/main.92bfa60e.chunk.js.map",
4+
"main.js": "/static/js/main.2368c861.chunk.js",
5+
"main.js.map": "/static/js/main.2368c861.chunk.js.map",
66
"runtime-main.js": "/static/js/runtime-main.f48e99e5.js",
77
"runtime-main.js.map": "/static/js/runtime-main.f48e99e5.js.map",
88
"static/css/2.f324abd6.chunk.css": "/static/css/2.f324abd6.chunk.css",
9-
"static/js/2.26e254ca.chunk.js": "/static/js/2.26e254ca.chunk.js",
10-
"static/js/2.26e254ca.chunk.js.map": "/static/js/2.26e254ca.chunk.js.map",
9+
"static/js/2.e01324bd.chunk.js": "/static/js/2.e01324bd.chunk.js",
10+
"static/js/2.e01324bd.chunk.js.map": "/static/js/2.e01324bd.chunk.js.map",
1111
"index.html": "/index.html",
1212
"static/css/2.f324abd6.chunk.css.map": "/static/css/2.f324abd6.chunk.css.map",
1313
"static/css/main.a19f3d53.chunk.css.map": "/static/css/main.a19f3d53.chunk.css.map",
14-
"static/js/2.26e254ca.chunk.js.LICENSE.txt": "/static/js/2.26e254ca.chunk.js.LICENSE.txt",
14+
"static/js/2.e01324bd.chunk.js.LICENSE.txt": "/static/js/2.e01324bd.chunk.js.LICENSE.txt",
1515
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
1616
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
1717
},
1818
"entrypoints": [
1919
"static/js/runtime-main.f48e99e5.js",
2020
"static/css/2.f324abd6.chunk.css",
21-
"static/js/2.26e254ca.chunk.js",
21+
"static/js/2.e01324bd.chunk.js",
2222
"static/css/main.a19f3d53.chunk.css",
23-
"static/js/main.92bfa60e.chunk.js"
23+
"static/js/main.2368c861.chunk.js"
2424
]
2525
}

portal-ui/build/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.f324abd6.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.26e254ca.chunk.js"></script><script src="/static/js/main.92bfa60e.chunk.js"></script></body></html>
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.f324abd6.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.e01324bd.chunk.js"></script><script src="/static/js/main.2368c861.chunk.js"></script></body></html>

portal-ui/build/static/js/2.26e254ca.chunk.js renamed to portal-ui/build/static/js/2.e01324bd.chunk.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portal-ui/build/static/js/2.26e254ca.chunk.js.map renamed to portal-ui/build/static/js/2.e01324bd.chunk.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portal-ui/build/static/js/main.92bfa60e.chunk.js renamed to portal-ui/build/static/js/main.2368c861.chunk.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portal-ui/build/static/js/main.2368c861.chunk.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)