Skip to content
This repository has been archived by the owner on May 18, 2021. It is now read-only.

Log in via the saml URL if the profile contains one #114

Merged
merged 2 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ func loginRun(cmd *cobra.Command, args []string) error {
return err
}

if _, ok := profiles[profile]; !ok {
prof, ok := profiles[profile]
if !ok {
return fmt.Errorf("Profile '%s' not found in your aws config", profile)
}

Expand Down Expand Up @@ -108,6 +109,31 @@ func loginRun(cmd *cobra.Command, args []string) error {
return err
}

if _, ok := prof["aws_saml_url"]; ok {
oktaLogin(p)
} else {
federatedLogin(p, profile, profiles)
}

return nil
}

func oktaLogin(p *lib.Provider) error {
loginURL, err := p.GetSamlLoginURL()
if err != nil {
return err
}

if Stdout {
fmt.Println(loginURL.String())
} else if err := open.Run(loginURL.String()); err != nil {
return err
}

return nil
}

func federatedLogin(p *lib.Provider, profile string, profiles lib.Profiles) error {
creds, err := p.Retrieve()
if err != nil {
return err
Expand Down
36 changes: 36 additions & 0 deletions lib/okta.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,3 +536,39 @@ func (p *OktaProvider) Retrieve() (sts.Credentials, string, error) {

return creds, oktaCreds.Username, err
}

func (p *OktaProvider) GetSamlLoginURL() (*url.URL, error) {
Fauzyy marked this conversation as resolved.
Show resolved Hide resolved
item, err := p.Keyring.Get("okta-creds")
if err != nil {
log.Debugf("couldnt get okta creds from keyring: %s", err)
return &url.URL{}, err
}

var oktaCreds OktaCreds
if err = json.Unmarshal(item.Data, &oktaCreds); err != nil {
return &url.URL{}, errors.New("Failed to get okta credentials from your keyring. Please make sure you have added okta credentials with `aws-okta add`")
}

var samlURL string

// maintain compatibility for deprecated creds.Organization
if oktaCreds.Domain == "" && oktaCreds.Organization != "" {
samlURL = fmt.Sprintf("%s.%s", oktaCreds.Organization, OktaServerDefault)
} else if oktaCreds.Domain != "" {
samlURL = oktaCreds.Domain
} else {
return &url.URL{}, errors.New("either oktaCreds.Organization (deprecated) or oktaCreds.Domain must be set, but not both. To remedy this, re-add your credentials with `aws-okta add`")
}

fullSamlURL, err := url.Parse(fmt.Sprintf(
"https://%s/%s",
samlURL,
p.OktaAwsSAMLUrl,
))

if err != nil {
return &url.URL{}, err
}

return fullSamlURL, nil
}
30 changes: 30 additions & 0 deletions lib/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package lib
import (
"errors"
"fmt"
"net/url"
"time"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -183,6 +184,35 @@ func (p *Provider) getSamlSessionCreds() (sts.Credentials, error) {
return creds, nil
}

func (p *Provider) GetSamlLoginURL() (*url.URL, error) {
source := sourceProfile(p.profile, p.profiles)
oktaAwsSAMLUrl, err := p.getSamlURL()
if err != nil {
return &url.URL{}, err
}
oktaSessionCookieKey := p.getOktaSessionCookieKey()

profileARN, ok := p.profiles[source]["role_arn"]
if !ok {
return &url.URL{}, errors.New("Source profile must provide `role_arn`")
}

provider := OktaProvider{
MFADevice: p.ProviderOptions.MFADevice,
Keyring: p.keyring,
ProfileARN: profileARN,
SessionDuration: p.SessionDuration,
OktaAwsSAMLUrl: oktaAwsSAMLUrl,
OktaSessionCookieKey: oktaSessionCookieKey,
}

loginURL, err := provider.GetSamlLoginURL()
if err != nil {
return &url.URL{}, err
}
return loginURL, nil
}

// assumeRoleFromSession takes a session created with an okta SAML login and uses that to assume a role
func (p *Provider) assumeRoleFromSession(creds sts.Credentials, roleArn string) (sts.Credentials, error) {
client := sts.New(session.New(&aws.Config{Credentials: credentials.NewStaticCredentials(
Expand Down