forked from oktadev/okta-aws-cli-assume-role
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OktaAwsCliAssumeRole.java
167 lines (132 loc) · 6.5 KB
/
OktaAwsCliAssumeRole.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
* Copyright 2017 Okta
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.okta.tools;
import java.io.IOException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.okta.tools.authentication.*;
import com.okta.tools.helpers.*;
import com.okta.tools.saml.OktaAppClient;
import com.okta.tools.saml.OktaAppClientImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.amazonaws.services.securitytoken.model.AssumeRoleWithSAMLRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleWithSAMLResult;
import com.okta.tools.models.Profile;
import com.okta.tools.models.Session;
import com.okta.tools.saml.OktaSaml;
final class OktaAwsCliAssumeRole {
private static final Logger logger = LogManager.getLogger(OktaAwsCliAssumeRole.class);
private OktaAwsCliEnvironment environment;
private SessionHelper sessionHelper;
private RoleHelper roleHelper;
private CredentialsHelper credentialsHelper;
private ProfileHelper profileHelper;
private OktaSaml oktaSaml;
private Optional<Session> currentSession;
private Optional<Profile> currentProfile;
static OktaAwsCliAssumeRole withEnvironment(OktaAwsCliEnvironment environment) {
return new OktaAwsCliAssumeRole(environment);
}
private OktaAwsCliAssumeRole(OktaAwsCliEnvironment environment) {
this.environment = environment;
}
private void init() throws Exception {
CookieHelper cookieHelper = new CookieHelper(environment);
sessionHelper = new SessionHelper(environment, cookieHelper);
roleHelper = new RoleHelper(environment);
credentialsHelper = new CredentialsHelper(environment);
profileHelper = new ProfileHelper(credentialsHelper, environment);
MenuHelper menuHelper = new MenuHelperImpl();
OktaFactorSelector factorSelector = new OktaFactorSelectorImpl(environment, menuHelper);
OktaMFA oktaMFA = new OktaMFA(factorSelector);
UserConsole userConsole = new UserConsoleImpl();
OktaAuthnClient oktaAuthnClient = new OktaAuthnClientImpl();
OktaAuthentication oktaAuthentication = new OktaAuthentication(environment, oktaMFA, userConsole, oktaAuthnClient);
OktaAppClient oktaAppClient = new OktaAppClientImpl(cookieHelper);
oktaSaml = new OktaSaml(environment, oktaAuthentication, oktaAppClient);
currentSession = sessionHelper.getCurrentSession();
if (StringUtils.isEmpty(environment.oktaProfile)) {
if (currentSession.isPresent()) {
environment.oktaProfile = currentSession.get().profileName;
}
}
currentProfile = sessionHelper.getFromMultipleProfiles();
}
RunResult run(Instant startInstant) throws Exception {
init();
environment.awsRoleToAssume = currentProfile.map(profile1 -> profile1.roleArn).orElse(environment.awsRoleToAssume);
if (currentSession.isPresent() && sessionHelper.sessionIsActive(startInstant, currentSession.get())) {
RunResult runResult = new RunResult();
runResult.profileName = currentSession.get().profileName;
return runResult;
}
ProfileSAMLResult profileSAMLResult = doRequest(startInstant);
RunResult runResult = new RunResult();
runResult.profileName = profileSAMLResult.profileName;
Credentials credentials = profileSAMLResult.assumeRoleWithSAMLResult.getCredentials();
runResult.accessKeyId = credentials.getAccessKeyId();
runResult.secretAccessKey = credentials.getSecretAccessKey();
runResult.sessionToken = credentials.getSessionToken();
return runResult;
}
class RunResult {
String profileName;
String accessKeyId;
String secretAccessKey;
String sessionToken;
}
AssumeRoleWithSAMLResult getAssumeRoleWithSAMLResult(Instant startInstant) throws Exception {
init();
environment.awsRoleToAssume = currentProfile.map(profile1 -> profile1.roleArn).orElse(environment.awsRoleToAssume);
ProfileSAMLResult profileSAMLResult = doRequest(startInstant);
return profileSAMLResult.assumeRoleWithSAMLResult;
}
private ProfileSAMLResult doRequest(Instant startInstant) throws IOException {
String samlResponse = oktaSaml.getSamlResponse();
AssumeRoleWithSAMLRequest assumeRequest = roleHelper.chooseAwsRoleToAssume(samlResponse);
Instant sessionExpiry = startInstant.plus(assumeRequest.getDurationSeconds() - 30, ChronoUnit.SECONDS);
AssumeRoleWithSAMLResult assumeResult = roleHelper.assumeChosenAwsRole(assumeRequest);
String profileName = profileHelper.getProfileName(assumeResult);
if (!environment.oktaEnvMode) {
profileHelper.createAwsProfile(assumeResult, profileName);
updateConfig(assumeRequest, sessionExpiry, profileName);
}
return new ProfileSAMLResult(assumeResult, profileName);
}
private void updateConfig(AssumeRoleWithSAMLRequest assumeRequest, Instant sessionExpiry, String profileName) throws IOException {
environment.oktaProfile = profileName;
environment.awsRoleToAssume = assumeRequest.getRoleArn();
sessionHelper.addOrUpdateProfile(sessionExpiry);
sessionHelper.updateCurrentSession(sessionExpiry, profileName);
}
// Holds the values for the profile name and SAML result shared by CLI and SDK implementations
private class ProfileSAMLResult {
String profileName;
AssumeRoleWithSAMLResult assumeRoleWithSAMLResult;
ProfileSAMLResult(AssumeRoleWithSAMLResult pAssumeRoleWithSAMLResult, String pProfileName) {
assumeRoleWithSAMLResult = pAssumeRoleWithSAMLResult;
profileName = pProfileName;
}
}
public void logoutSession() throws Exception {
init();
sessionHelper.logoutCurrentSession();
}
}