Adds the ability to bypass Okta MFA checks. (#3944)

* Adds the ability to bypass Okta MFA checks.

Unlike before, the administrator opts-in to this behavior, and is
suitably warned.

Fixes #3872
This commit is contained in:
Jeff Mitchell 2018-02-09 17:03:49 -05:00 committed by GitHub
parent 65328e9c12
commit a9a322aa39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 12 deletions

View File

@ -115,6 +115,11 @@ func (b *backend) Login(ctx context.Context, req *logical.Request, username stri
case "PASSWORD_WARN":
oktaResponse.AddWarning("Your Okta password is in warning state and needs to be changed soon.")
case "MFA_REQUIRED", "MFA_ENROLL":
if !cfg.BypassOktaMFA {
return nil, logical.ErrorResponse("okta mfa required for this account but mfa bypass not set in config"), nil, nil
}
case "SUCCESS":
// Do nothing here
@ -126,7 +131,13 @@ func (b *backend) Login(ctx context.Context, req *logical.Request, username stri
}
// Verify result status again in case a switch case above modifies result
if result.Status != "SUCCESS" && result.Status != "PASSWORD_WARN" {
switch {
case result.Status == "SUCCESS",
result.Status == "PASSWORD_WARN",
result.Status == "MFA_REQUIRED" && cfg.BypassOktaMFA,
result.Status == "MFA_ENROLL" && cfg.BypassOktaMFA:
// Allowed
default:
if b.Logger().IsDebug() {
b.Logger().Debug("auth/okta: authentication returned a non-success status", "status", result.Status)
}

View File

@ -54,6 +54,10 @@ func pathConfig(b *backend) *framework.Path {
Type: framework.TypeDurationSecond,
Description: `Maximum duration after which authentication will be expired`,
},
"bypass_okta_mfa": &framework.FieldSchema{
Type: framework.TypeBool,
Description: `When set true, requests by Okta for a MFA check will be bypassed. This also disallows certain status checks on the account, such as whether the password is expired.`,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
@ -103,6 +107,7 @@ func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, d *f
"org_name": cfg.Org,
"ttl": cfg.TTL.Seconds(),
"max_ttl": cfg.MaxTTL.Seconds(),
"bypass_okta_mfa": cfg.BypassOktaMFA,
},
}
if cfg.BaseURL != "" {
@ -112,6 +117,10 @@ func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, d *f
resp.Data["production"] = *cfg.Production
}
if cfg.BypassOktaMFA {
resp.AddWarning("Okta MFA bypass is configured. In addition to ignoring Okta MFA requests, certain other account statuses will not be seen, such as PASSWORD_EXPIRED. Authentication will succeed in these cases.")
}
return resp, nil
}
@ -175,6 +184,11 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, d *
cfg.Production = nil
}
bypass, ok := d.GetOk("bypass_okta_mfa")
if ok {
cfg.BypassOktaMFA = bypass.(bool)
}
ttl, ok := d.GetOk("ttl")
if ok {
cfg.TTL = time.Duration(ttl.(int)) * time.Second
@ -197,7 +211,13 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, d *
return nil, err
}
return nil, nil
var resp *logical.Response
if cfg.BypassOktaMFA {
resp = new(logical.Response)
resp.AddWarning("Okta MFA bypass is configured. In addition to ignoring Okta MFA requests, certain other account statuses will not be seen, such as PASSWORD_EXPIRED. Authentication will succeed in these cases.")
}
return resp, nil
}
func (b *backend) pathConfigExistenceCheck(ctx context.Context, req *logical.Request, d *framework.FieldData) (bool, error) {
@ -234,6 +254,7 @@ type ConfigEntry struct {
Production *bool `json:"is_production,omitempty"`
TTL time.Duration `json:"ttl"`
MaxTTL time.Duration `json:"max_ttl"`
BypassOktaMFA bool `json:"bypass_okta_mfa"`
}
const pathConfigHelp = `

View File

@ -37,6 +37,9 @@ distinction between the `create` and `update` capabilities inside ACL policies.
- `ttl` `(string: "")` - Duration after which authentication will be expired.
- `max_ttl` `(string: "")` - Maximum duration after which authentication will
be expired.
- `bypass_okta_mfa` `(bool: false)` - Whether to bypass an Okta MFA request.
Useful if using one of Vault's built-in MFA mechanisms, but this will also
cause certain other statuses to be ignored, such as `PASSWORD_EXPIRED`.
### Sample Payload