Skip to content

Commit f6ac7e0

Browse files
authored
Invalidate console session when minio user doesn't exists (#332)
1 parent e1fdf3f commit f6ac7e0

File tree

12 files changed

+28
-37
lines changed

12 files changed

+28
-37
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ Additionally, you can create policies to limit the privileges for `console` user
101101
To run the server:
102102

103103
```
104-
export CONSOLE_HMAC_JWT_SECRET=YOURJWTSIGNINGSECRET
105-
106104
#required to encrypt jwet payload
107105
export CONSOLE_PBKDF_PASSPHRASE=SECRET
108106

docs/console_operator_mode.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
`Console` will authenticate against `Kubernetes`using bearer tokens via HTTP `Authorization` header. The user will provide this token once
44
in the login form, Console will validate it against Kubernetes (list apis) and if valid will generate and return a new Console sessions
5-
with encrypted claims (the user Service account token will be inside the JWT in the data field)
5+
with encrypted claims (the user Service account token will be inside the session encrypted token
66

77
# Kubernetes
88

pkg/auth/token/config.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ import (
2323
"github.com/minio/minio/pkg/env"
2424
)
2525

26-
// ConsoleSTSAndJWTDurationSeconds returns the default session duration for the STS requested tokens and the generated JWTs.
27-
// Ideally both values should match so jwt and Minio sts sessions expires at the same time.
28-
func GetConsoleSTSAndJWTDurationInSeconds() int {
29-
duration, err := strconv.Atoi(env.Get(ConsoleSTSAndJWTDurationSeconds, "3600"))
26+
// ConsoleSTSDurationSeconds returns the default session duration for the STS requested tokens.
27+
func GetConsoleSTSDurationInSeconds() int {
28+
duration, err := strconv.Atoi(env.Get(ConsoleSTSDurationSeconds, "3600"))
3029
if err != nil {
3130
duration = 3600
3231
}

pkg/auth/token/const.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package token
1818

1919
const (
20-
ConsoleSTSAndJWTDurationSeconds = "CONSOLE_STS_AND_JWT_DURATION_SECONDS"
21-
ConsolePBKDFPassphrase = "CONSOLE_PBKDF_PASSPHRASE"
22-
ConsolePBKDFSalt = "CONSOLE_PBKDF_SALT"
20+
ConsoleSTSDurationSeconds = "CONSOLE_STS_DURATION_SECONDS"
21+
ConsolePBKDFPassphrase = "CONSOLE_PBKDF_PASSPHRASE"
22+
ConsolePBKDFSalt = "CONSOLE_PBKDF_SALT"
2323
)

pkg/auth/token_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,17 @@ func TestJWTAuthenticate(t *testing.T) {
6060
funcAssert.Equal(claims.SecretAccessKey, creds.SecretAccessKey)
6161
funcAssert.Equal(claims.SessionToken, creds.SessionToken)
6262
}
63-
// Test-2 : SessionTokenAuthenticate() return an error because of a tampered jwt
63+
// Test-2 : SessionTokenAuthenticate() return an error because of a tampered token
6464
if _, err := SessionTokenAuthenticate(badToken); err != nil {
6565
funcAssert.Equal("session token internal data is malformed", err.Error())
6666
}
67-
// Test-3 : SessionTokenAuthenticate() return an error because of an empty jwt
67+
// Test-3 : SessionTokenAuthenticate() return an error because of an empty token
6868
if _, err := SessionTokenAuthenticate(""); err != nil {
6969
funcAssert.Equal("session token missing", err.Error())
7070
}
7171
}
7272

73-
func TestIsJWTValid(t *testing.T) {
73+
func TestSessionTokenValid(t *testing.T) {
7474
funcAssert := assert.New(t)
7575
// Test-1 : SessionTokenAuthenticate() provided token is valid
7676
funcAssert.Equal(true, IsSessionTokenValid(goodToken))

restapi/admin_tenants.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,6 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
646646
},
647647
Immutable: &imm,
648648
Data: map[string][]byte{
649-
"CONSOLE_HMAC_JWT_SECRET": []byte(RandomCharString(16)),
650649
"CONSOLE_PBKDF_PASSPHRASE": []byte(RandomCharString(16)),
651650
"CONSOLE_PBKDF_SALT": []byte(RandomCharString(8)),
652651
"CONSOLE_ACCESS_KEY": []byte(consoleAccess),

restapi/client.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ func newConsoleCredentials(accessKey, secretKey, location string) (*credentials.
260260
AccessKey: accessKey,
261261
SecretKey: secretKey,
262262
Location: location,
263-
DurationSeconds: xjwt.GetConsoleSTSAndJWTDurationInSeconds(),
263+
DurationSeconds: xjwt.GetConsoleSTSDurationInSeconds(),
264264
}
265265
stsClient := PrepareSTSClient(false)
266266
stsAssumeRole := &credentials.STSAssumeRole{
@@ -274,23 +274,14 @@ func newConsoleCredentials(accessKey, secretKey, location string) (*credentials.
274274
}
275275
}
276276

277-
// GetClaimsFromJWT decrypt and returns the claims associated to a provided jwt
278-
func GetClaimsFromJWT(jwt string) (*auth.DecryptedClaims, error) {
279-
claims, err := auth.SessionTokenAuthenticate(jwt)
280-
if err != nil {
281-
return nil, err
282-
}
283-
return claims, nil
284-
}
285-
286277
// getConsoleCredentialsFromSession returns the *consoleCredentials.Login associated to the
287-
// provided jwt, this is useful for running the Expire() or IsExpired() operations
278+
// provided session token, this is useful for running the Expire() or IsExpired() operations
288279
func getConsoleCredentialsFromSession(claims *models.Principal) *credentials.Credentials {
289280
return credentials.NewStaticV4(claims.AccessKeyID, claims.SecretAccessKey, claims.SessionToken)
290281
}
291282

292283
// newMinioClient creates a new MinIO client based on the consoleCredentials extracted
293-
// from the provided jwt
284+
// from the provided session token
294285
func newMinioClient(claims *models.Principal) (*minio.Client, error) {
295286
creds := getConsoleCredentialsFromSession(claims)
296287
stsClient := PrepareSTSClient(false)

restapi/configure_console.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
6161
// Applies when the "x-token" header is set
6262

6363
api.KeyAuth = func(token string, scopes []string) (*models.Principal, error) {
64-
// we are validating the jwt by decrypting the claims inside, if the operation succed that means the jwt
64+
// we are validating the session token by decrypting the claims inside, if the operation succeed that means the jwt
6565
// was generated and signed by us in the first place
6666
claims, err := auth.SessionTokenAuthenticate(token)
6767
if err != nil {

restapi/error.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ func prepareError(err ...error) *models.Error {
8787
errorCode = 401
8888
errorMessage = errorGenericInvalidSession.Error()
8989
}
90+
if madmin.ToErrorResponse(err[0]).Code == "InvalidAccessKeyId" {
91+
errorCode = 401
92+
errorMessage = errorGenericInvalidSession.Error()
93+
}
9094
// console invalid session error
9195
if madmin.ToErrorResponse(err[0]).Code == "XMinioAdminNoSuchUser" {
9296
errorCode = 401

restapi/user_login.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ func login(credentials ConsoleCredentials, actions []string) (*string, error) {
7272
return nil, err
7373
}
7474
// if we made it here, the consoleCredentials work, generate a jwt with claims
75-
jwt, err := auth.NewEncryptedTokenForClient(&tokens, actions)
75+
token, err := auth.NewEncryptedTokenForClient(&tokens, actions)
7676
if err != nil {
7777
log.Println("error authenticating user", err)
7878
return nil, errInvalidCredentials
7979
}
80-
return &jwt, nil
80+
return &token, nil
8181
}
8282

8383
func getConfiguredRegionForLogin(client MinioAdmin) (string, error) {
@@ -224,19 +224,19 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
224224
return nil, prepareError(err)
225225
}
226226
actions := acl.GetActionsStringFromPolicy(policy)
227-
// User was created correctly, create a new session/JWT
227+
// User was created correctly, create a new session
228228
creds, err := newConsoleCredentials(accessKey, secretKey, location)
229229
if err != nil {
230230
return nil, prepareError(err)
231231
}
232232
credentials := consoleCredentials{consoleCredentials: creds}
233-
jwt, err := login(credentials, actions)
233+
token, err := login(credentials, actions)
234234
if err != nil {
235235
return nil, prepareError(errInvalidCredentials, nil, err)
236236
}
237237
// serialize output
238238
loginResponse := &models.LoginResponse{
239-
SessionID: *jwt,
239+
SessionID: *token,
240240
}
241241
return loginResponse, nil
242242
}
@@ -251,13 +251,13 @@ func getLoginOperatorResponse(lmr *models.LoginOperatorRequest) (*models.LoginRe
251251
}
252252
credentials := consoleCredentials{consoleCredentials: creds}
253253
var actions []string
254-
jwt, err := login(credentials, actions)
254+
token, err := login(credentials, actions)
255255
if err != nil {
256256
return nil, prepareError(errInvalidCredentials, nil, err)
257257
}
258258
// serialize output
259259
loginResponse := &models.LoginResponse{
260-
SessionID: *jwt,
260+
SessionID: *token,
261261
}
262262
return loginResponse, nil
263263
}

0 commit comments

Comments
 (0)