From 7764c542f22ecd73099099c309e20c590154593a Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 19 Jul 2020 15:34:01 -0700 Subject: [PATCH] allow claims to be optional in STS (#10078) not all claims need to be present for the JWT claim, let the policies not exist and only apply which are present when generating the credentials once credentials are generated then those policies should exist, otherwise the request will fail. --- cmd/iam.go | 28 ++++++++++++++++++++++++---- cmd/sts-handlers.go | 26 ++++++++++++++++---------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/cmd/iam.go b/cmd/iam.go index 1bd46e84e..1007be641 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -675,6 +675,24 @@ func (sys *IAMSys) DeleteUser(accessKey string) error { return err } +// returns comma separated policy string, from an input policy +// after validating if there are any current policies which exist +// on MinIO corresponding to the input. +func (sys *IAMSys) currentPolicies(policyName string) string { + sys.store.rlock() + defer sys.store.runlock() + + var policies []string + mp := newMappedPolicy(policyName) + for _, policy := range mp.toSlice() { + _, found := sys.iamPolicyDocsMap[policy] + if found { + policies = append(policies, policy) + } + } + return strings.Join(policies, ",") +} + // SetTempUser - set temporary user credentials, these credentials have an expiry. func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyName string) error { objectAPI := newObjectLayerWithoutSafeModeFn() @@ -693,10 +711,9 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa mp := newMappedPolicy(policyName) for _, policy := range mp.toSlice() { p, found := sys.iamPolicyDocsMap[policy] - if !found { - return fmt.Errorf("%w: (%s)", errNoSuchPolicy, policy) + if found { + availablePolicies = append(availablePolicies, p) } - availablePolicies = append(availablePolicies, p) } combinedPolicy := availablePolicies[0] @@ -1671,6 +1688,7 @@ func (sys *IAMSys) IsAllowedLDAPSTS(args iampolicy.Args) bool { for _, pname := range mp.toSlice() { p, found := sys.iamPolicyDocsMap[pname] if !found { + logger.LogIf(GlobalContext, fmt.Errorf("expected policy (%s) missing for the LDAPUser %s, rejecting the request", pname, user)) return false } policies = append(policies, p) @@ -1684,6 +1702,7 @@ func (sys *IAMSys) IsAllowedLDAPSTS(args iampolicy.Args) bool { for _, pname := range mp.toSlice() { p, found := sys.iamPolicyDocsMap[pname] if !found { + logger.LogIf(GlobalContext, fmt.Errorf("expected policy (%s) missing for the LDAPGroup %s, rejecting the request", pname, group)) return false } policies = append(policies, p) @@ -1744,7 +1763,8 @@ func (sys *IAMSys) IsAllowedSTS(args iampolicy.Args) bool { for pname := range policies { p, found := sys.iamPolicyDocsMap[pname] if !found { - logger.LogIf(GlobalContext, fmt.Errorf("%w: (%s)", errNoSuchPolicy, pname)) + // all policies presented in the claim should exist + logger.LogIf(GlobalContext, fmt.Errorf("expected policy (%s) missing from the JWT claim %s, rejecting the request", pname, iamPolicyClaimNameOpenID())) return false } availablePolicies = append(availablePolicies, p) diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 4d1cfb299..0e66df47e 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -318,6 +318,22 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ return } + // JWT has requested a custom claim with policy value set. + // This is a MinIO STS API specific value, this value should + // be set and configured on your identity provider as part of + // JWT custom claims. + var policyName string + policySet, ok := iampolicy.GetPoliciesFromClaims(m, iamPolicyClaimNameOpenID()) + if ok { + policyName = globalIAMSys.currentPolicies(strings.Join(policySet.ToSlice(), ",")) + } + + if policyName == "" { + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("%s claim missing from the JWT token, credentials will not be generated", iamPolicyClaimNameOpenID())) + return + } + m[iamPolicyClaimNameOpenID()] = policyName + sessionPolicyStr := r.Form.Get(stsPolicy) // https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html // The plain text that you use for both inline and managed session @@ -352,16 +368,6 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ return } - // JWT has requested a custom claim with policy value set. - // This is a MinIO STS API specific value, this value should - // be set and configured on your identity provider as part of - // JWT custom claims. - var policyName string - policySet, ok := iampolicy.GetPoliciesFromClaims(m, iamPolicyClaimNameOpenID()) - if ok { - policyName = strings.Join(policySet.ToSlice(), ",") - } - var subFromToken string if v, ok := m[subClaim]; ok { subFromToken, _ = v.(string)