mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
assumeRole return the correct http code for auth errors (#16967)
This commit is contained in:
parent
62c3df0ca3
commit
111c7d4026
@ -371,7 +371,7 @@ func deleteObjectVersions(ctx context.Context, o ObjectLayer, bucket string, toD
|
||||
auditLogLifecycle(
|
||||
ctx,
|
||||
ObjectInfo{
|
||||
Bucket: bucket,
|
||||
Bucket: bucket,
|
||||
Name: dobj.ObjectName,
|
||||
VersionID: dobj.VersionID,
|
||||
},
|
||||
|
@ -27,19 +27,9 @@ import (
|
||||
)
|
||||
|
||||
// writeSTSErrorRespone writes error headers
|
||||
func writeSTSErrorResponse(ctx context.Context, w http.ResponseWriter, isErrCodeSTS bool, errCode STSErrorCode, errCtxt error) {
|
||||
var err STSError
|
||||
if isErrCodeSTS {
|
||||
err = stsErrCodes.ToSTSErr(errCode)
|
||||
}
|
||||
if err.Code == "InternalError" || !isErrCodeSTS {
|
||||
aerr := errorCodes.ToAPIErr(toAPIErrorCode(ctx, errCtxt))
|
||||
if aerr.Code != "InternalError" {
|
||||
err.Code = aerr.Code
|
||||
err.Description = aerr.Description
|
||||
err.HTTPStatusCode = aerr.HTTPStatusCode
|
||||
}
|
||||
}
|
||||
func writeSTSErrorResponse(ctx context.Context, w http.ResponseWriter, errCode STSErrorCode, errCtxt error) {
|
||||
err := stsErrCodes.ToSTSErr(errCode)
|
||||
|
||||
// Generate error response.
|
||||
stsErrorResponse := STSErrorResponse{}
|
||||
stsErrorResponse.Error.Code = err.Code
|
||||
|
@ -137,32 +137,45 @@ func registerSTSRouter(router *mux.Router) {
|
||||
Queries(stsVersion, stsAPIVersion)
|
||||
}
|
||||
|
||||
func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (user auth.Credentials, isErrCodeSTS bool, stsErr STSErrorCode) {
|
||||
func apiToSTSError(authErr APIErrorCode) (stsErrCode STSErrorCode) {
|
||||
switch authErr {
|
||||
case ErrSignatureDoesNotMatch, ErrInvalidAccessKeyID, ErrAccessKeyDisabled:
|
||||
return ErrSTSAccessDenied
|
||||
case ErrServerNotInitialized:
|
||||
return ErrSTSNotInitialized
|
||||
case ErrInternalError:
|
||||
return ErrSTSInternalError
|
||||
default:
|
||||
return ErrSTSAccessDenied
|
||||
}
|
||||
}
|
||||
|
||||
func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (auth.Credentials, APIErrorCode) {
|
||||
if !isRequestSignatureV4(r) {
|
||||
return user, true, ErrSTSAccessDenied
|
||||
return auth.Credentials{}, ErrAccessDenied
|
||||
}
|
||||
|
||||
s3Err := isReqAuthenticated(ctx, r, globalSite.Region, serviceSTS)
|
||||
if s3Err != ErrNone {
|
||||
return user, false, STSErrorCode(s3Err)
|
||||
return auth.Credentials{}, s3Err
|
||||
}
|
||||
|
||||
user, _, s3Err = getReqAccessKeyV4(r, globalSite.Region, serviceSTS)
|
||||
user, _, s3Err := getReqAccessKeyV4(r, globalSite.Region, serviceSTS)
|
||||
if s3Err != ErrNone {
|
||||
return user, false, STSErrorCode(s3Err)
|
||||
return auth.Credentials{}, s3Err
|
||||
}
|
||||
|
||||
// Temporary credentials or Service accounts cannot generate further temporary credentials.
|
||||
if user.IsTemp() || user.IsServiceAccount() {
|
||||
return user, true, ErrSTSAccessDenied
|
||||
return auth.Credentials{}, ErrAccessDenied
|
||||
}
|
||||
|
||||
// Session tokens are not allowed in STS AssumeRole requests.
|
||||
if getSessionToken(r) != "" {
|
||||
return user, true, ErrSTSAccessDenied
|
||||
return auth.Credentials{}, ErrAccessDenied
|
||||
}
|
||||
|
||||
return user, true, ErrSTSNone
|
||||
return user, ErrNone
|
||||
}
|
||||
|
||||
func parseForm(r *http.Request) error {
|
||||
@ -190,15 +203,15 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
// the call to `parseForm` below), but return failure only after we are
|
||||
// able to validate that it is a valid STS request, so that we are able
|
||||
// to send an appropriate audit log.
|
||||
user, isErrCodeSTS, stsErr := checkAssumeRoleAuth(ctx, r)
|
||||
user, apiErrCode := checkAssumeRoleAuth(ctx, r)
|
||||
|
||||
if err := parseForm(r); err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Form.Get(stsVersion) != stsAPIVersion {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get(stsVersion), stsAPIVersion))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get(stsVersion), stsAPIVersion))
|
||||
return
|
||||
}
|
||||
|
||||
@ -206,16 +219,17 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
switch action {
|
||||
case assumeRole:
|
||||
default:
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
return
|
||||
}
|
||||
|
||||
ctx = newContext(r, w, action)
|
||||
|
||||
// Validate the authentication result here so that failures will be
|
||||
// audit-logged.
|
||||
if stsErr != ErrSTSNone {
|
||||
writeSTSErrorResponse(ctx, w, isErrCodeSTS, stsErr, nil)
|
||||
// Validate the authentication result here so that failures will be audit-logged.
|
||||
if apiErrCode != ErrNone {
|
||||
stsErr := apiToSTSError(apiErrCode)
|
||||
// Borrow the description error from the API error code
|
||||
writeSTSErrorResponse(ctx, w, stsErr, fmt.Errorf(errorCodes[apiErrCode].Description))
|
||||
return
|
||||
}
|
||||
|
||||
@ -224,27 +238,27 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
// The plain text that you use for both inline and managed session
|
||||
// policies shouldn't exceed 2048 characters.
|
||||
if len(sessionPolicyStr) > 2048 {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy shouldn't exceed 2048 characters"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy shouldn't exceed 2048 characters"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(sessionPolicyStr) > 0 {
|
||||
sessionPolicy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicyStr)))
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Version in policy must not be empty
|
||||
if sessionPolicy.Version == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Version cannot be empty expecting '2012-10-17'"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Version cannot be empty expecting '2012-10-17'"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
duration, err := openid.GetDefaultExpiration(r.Form.Get(stsDurationSeconds))
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -254,7 +268,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
// Validate that user.AccessKey's policies can be retrieved - it may not
|
||||
// be in case the user is disabled.
|
||||
if _, err = globalIAMSys.PolicyDBGet(user.AccessKey, false); err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -265,7 +279,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
secret := globalActiveCred.SecretKey
|
||||
cred, err := auth.GetNewCredentialsWithMetadata(claims, secret)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -276,7 +290,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
// Set the newly generated credentials.
|
||||
updatedAt, err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, "")
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -312,12 +326,12 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
// Parse the incoming form data.
|
||||
if err := parseForm(r); err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Form.Get(stsVersion) != stsAPIVersion {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion))
|
||||
return
|
||||
}
|
||||
|
||||
@ -328,7 +342,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
case clientGrants, webIdentity:
|
||||
default:
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
return
|
||||
}
|
||||
|
||||
@ -354,7 +368,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
var err error
|
||||
roleArn, _, err = globalIAMSys.GetRolePolicy(roleArnStr)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue,
|
||||
fmt.Errorf("Error processing %s parameter: %v", stsRoleArn, err))
|
||||
return
|
||||
}
|
||||
@ -366,16 +380,16 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
case openid.ErrTokenExpired:
|
||||
switch action {
|
||||
case clientGrants:
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSClientGrantsExpiredToken, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSClientGrantsExpiredToken, err)
|
||||
case webIdentity:
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSWebIdentityExpiredToken, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSWebIdentityExpiredToken, err)
|
||||
}
|
||||
return
|
||||
case auth.ErrInvalidDuration:
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -397,11 +411,11 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
if newGlobalAuthZPluginFn() == nil {
|
||||
if !ok {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue,
|
||||
fmt.Errorf("%s claim missing from the JWT token, credentials will not be generated", iamPolicyClaimNameOpenID()))
|
||||
return
|
||||
} else if policyName == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue,
|
||||
fmt.Errorf("None of the given policies (`%s`) are defined, credentials will not be generated", policies))
|
||||
return
|
||||
}
|
||||
@ -414,20 +428,20 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
// The plain text that you use for both inline and managed session
|
||||
// policies shouldn't exceed 2048 characters.
|
||||
if len(sessionPolicyStr) > 2048 {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(sessionPolicyStr) > 0 {
|
||||
sessionPolicy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicyStr)))
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Version in policy must not be empty
|
||||
if sessionPolicy.Version == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid session policy version"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid session policy version"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -437,7 +451,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
secret := globalActiveCred.SecretKey
|
||||
cred, err := auth.GetNewCredentialsWithMetadata(claims, secret)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -452,7 +466,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
}
|
||||
|
||||
if subFromToken == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue,
|
||||
errors.New("STS JWT Token has `sub` claim missing, `sub` claim is mandatory"))
|
||||
return
|
||||
}
|
||||
@ -477,7 +491,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
// Set the newly generated credentials.
|
||||
updatedAt, err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, policyName)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -549,12 +563,12 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
|
||||
// Parse the incoming form data.
|
||||
if err := parseForm(r); err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Form.Get(stsVersion) != stsAPIVersion {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter,
|
||||
fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion))
|
||||
return
|
||||
}
|
||||
@ -563,7 +577,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
ldapPassword := r.Form.Get(stsLDAPPassword)
|
||||
|
||||
if ldapUsername == "" || ldapPassword == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("LDAPUsername and LDAPPassword cannot be empty"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("LDAPUsername and LDAPPassword cannot be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -571,7 +585,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
switch action {
|
||||
case ldapIdentity:
|
||||
default:
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
return
|
||||
}
|
||||
|
||||
@ -580,20 +594,20 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
// The plain text that you use for both inline and managed session
|
||||
// policies shouldn't exceed 2048 characters.
|
||||
if len(sessionPolicyStr) > 2048 {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(sessionPolicyStr) > 0 {
|
||||
sessionPolicy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicyStr)))
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Version in policy must not be empty
|
||||
if sessionPolicy.Version == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Version needs to be specified in session policy"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Version needs to be specified in session policy"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -601,14 +615,14 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
ldapUserDN, groupDistNames, err := globalIAMSys.LDAPConfig.Bind(ldapUsername, ldapPassword)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("LDAP server error: %w", err)
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if this user or their groups have a policy applied.
|
||||
ldapPolicies, _ := globalIAMSys.PolicyDBGet(ldapUserDN, false, groupDistNames...)
|
||||
if len(ldapPolicies) == 0 && newGlobalAuthZPluginFn() == nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue,
|
||||
fmt.Errorf("expecting a policy to be set for user `%s` or one of their groups: `%s` - rejecting this request",
|
||||
ldapUserDN, strings.Join(groupDistNames, "`,`")))
|
||||
return
|
||||
@ -616,7 +630,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
|
||||
expiryDur, err := globalIAMSys.LDAPConfig.GetExpiryDuration(r.Form.Get(stsDurationSeconds))
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -631,7 +645,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
secret := globalActiveCred.SecretKey
|
||||
cred, err := auth.GetNewCredentialsWithMetadata(claims, secret)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -648,7 +662,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
// mapping.
|
||||
updatedAt, err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, "")
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -687,7 +701,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
defer logger.AuditLog(ctx, w, r, claims)
|
||||
|
||||
if !globalIAMSys.STSTLSConfig.Enabled {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSNotInitialized, errors.New("STS API 'AssumeRoleWithCertificate' is disabled"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSNotInitialized, errors.New("STS API 'AssumeRoleWithCertificate' is disabled"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -696,7 +710,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
// Otherwise, we don't have a certificate to verify or
|
||||
// the policy lookup would ambigious.
|
||||
if r.TLS == nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInsecureConnection, errors.New("No TLS connection attempt"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInsecureConnection, errors.New("No TLS connection attempt"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -718,11 +732,11 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
// Now, we have to check that the client has provided exactly one leaf
|
||||
// certificate that we can map to a policy.
|
||||
if len(r.TLS.PeerCertificates) == 0 {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, errors.New("No client certificate provided"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, errors.New("No client certificate provided"))
|
||||
return
|
||||
}
|
||||
if len(r.TLS.PeerCertificates) > 1 {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, errors.New("More than one client certificate provided"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, errors.New("More than one client certificate provided"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -735,7 +749,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
Roots: globalRootCAs,
|
||||
})
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidClientCertificate, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidClientCertificate, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -760,7 +774,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
}
|
||||
}
|
||||
if !validKeyUsage {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, errors.New("certificate is not valid for client authentication"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, errors.New("certificate is not valid for client authentication"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -772,13 +786,13 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
//
|
||||
// Group mapping is not possible with standard X.509 certificates.
|
||||
if certificate.Subject.CommonName == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, errors.New("certificate subject CN cannot be empty"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, errors.New("certificate subject CN cannot be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
expiry, err := globalIAMSys.STSTLSConfig.GetExpiryDuration(r.Form.Get(stsDurationSeconds))
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -801,7 +815,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
|
||||
tmpCredentials, err := auth.GetNewCredentialsWithMetadata(claims, globalActiveCred.SecretKey)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -809,7 +823,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
policyName := certificate.Subject.CommonName
|
||||
updatedAt, err := globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, policyName)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -845,19 +859,19 @@ func (sts *stsAPIHandlers) AssumeRoleWithCustomToken(w http.ResponseWriter, r *h
|
||||
|
||||
authn := newGlobalAuthNPluginFn()
|
||||
if authn == nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSNotInitialized, errors.New("STS API 'AssumeRoleWithCustomToken' is disabled"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSNotInitialized, errors.New("STS API 'AssumeRoleWithCustomToken' is disabled"))
|
||||
return
|
||||
}
|
||||
|
||||
action := r.Form.Get(stsAction)
|
||||
if action != customTokenIdentity {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action))
|
||||
return
|
||||
}
|
||||
|
||||
token := r.Form.Get(stsToken)
|
||||
if token == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid empty `Token` parameter provided"))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid empty `Token` parameter provided"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -867,7 +881,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCustomToken(w http.ResponseWriter, r *h
|
||||
var err error
|
||||
requestedDuration, err = strconv.Atoi(durationParam)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid requested duration: %s", durationParam))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid requested duration: %s", durationParam))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -875,26 +889,26 @@ func (sts *stsAPIHandlers) AssumeRoleWithCustomToken(w http.ResponseWriter, r *h
|
||||
roleArnStr := r.Form.Get(stsRoleArn)
|
||||
roleArn, _, err := globalIAMSys.GetRolePolicy(roleArnStr)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue,
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue,
|
||||
fmt.Errorf("Error processing parameter %s: %v", stsRoleArn, err))
|
||||
return
|
||||
}
|
||||
|
||||
res, err := authn.Authenticate(roleArn, token)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err)
|
||||
return
|
||||
}
|
||||
|
||||
// If authentication failed, return the error message to the user.
|
||||
if res.Failure != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSUpstreamError, errors.New(res.Failure.Reason))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSUpstreamError, errors.New(res.Failure.Reason))
|
||||
return
|
||||
}
|
||||
|
||||
// It is required that parent user be set.
|
||||
if res.Success.User == "" {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSUpstreamError, errors.New("A valid user was not returned by the authenticator."))
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSUpstreamError, errors.New("A valid user was not returned by the authenticator."))
|
||||
return
|
||||
}
|
||||
|
||||
@ -923,14 +937,14 @@ func (sts *stsAPIHandlers) AssumeRoleWithCustomToken(w http.ResponseWriter, r *h
|
||||
|
||||
tmpCredentials, err := auth.GetNewCredentialsWithMetadata(claims, globalActiveCred.SecretKey)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
tmpCredentials.ParentUser = parentUser
|
||||
updatedAt, err := globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, "")
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user