Skip to content

Commit 1ba2b5c

Browse files
authored
Merge pull request #109 from jianghaolu/09232016
Cumulative changes in runtime
2 parents 64c3003 + a46aaaa commit 1ba2b5c

File tree

12 files changed

+304
-214
lines changed

12 files changed

+304
-214
lines changed

azure-client-authentication/src/main/java/com/microsoft/azure/credentials/ApplicationTokenCredentials.java

Lines changed: 35 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,32 @@
1212
import com.microsoft.aad.adal4j.ClientCredential;
1313
import com.microsoft.azure.AzureEnvironment;
1414
import com.microsoft.rest.credentials.TokenCredentials;
15+
import okhttp3.OkHttpClient;
1516

1617
import java.io.File;
1718
import java.io.FileInputStream;
1819
import java.io.IOException;
20+
import java.util.Date;
21+
import java.util.HashMap;
22+
import java.util.Map;
1923
import java.util.Properties;
2024
import java.util.concurrent.ExecutorService;
2125
import java.util.concurrent.Executors;
2226

2327
/**
2428
* Token based credentials for use with a REST Service Client.
2529
*/
26-
public class ApplicationTokenCredentials extends TokenCredentials {
27-
/** The endpoint of the target resource. */
28-
private String resourceEndpoint;
30+
public class ApplicationTokenCredentials extends TokenCredentials implements AzureTokenCredentials {
31+
/** A mapping from resource endpoint to its cached access token. */
32+
private Map<String, AuthenticationResult> tokens;
33+
/** The Azure environment to authenticate with. */
34+
private AzureEnvironment environment;
2935
/** The active directory application client id. */
3036
private String clientId;
3137
/** The tenant or domain the containing the application. */
3238
private String domain;
3339
/** The authentication secret for the application. */
3440
private String secret;
35-
/** The Azure environment to authenticate with. */
36-
private AzureEnvironment environment;
37-
/** The current authentication result. */
38-
private AuthenticationResult authenticationResult;
3941
/** The default subscription to use, if any. */
4042
private String defaultSubscription;
4143

@@ -50,38 +52,11 @@ public class ApplicationTokenCredentials extends TokenCredentials {
5052
*/
5153
public ApplicationTokenCredentials(String clientId, String domain, String secret, AzureEnvironment environment) {
5254
super(null, null); // defer token acquisition
55+
this.environment = environment;
5356
this.clientId = clientId;
5457
this.domain = domain;
5558
this.secret = secret;
56-
if (environment == null) {
57-
this.environment = AzureEnvironment.AZURE;
58-
} else {
59-
this.environment = environment;
60-
}
61-
this.resourceEndpoint = this.environment.getTokenAudience();
62-
}
63-
64-
/**
65-
* Initializes a new instance of the UserTokenCredentials.
66-
*
67-
* @param clientId the active directory application client id.
68-
* @param domain the domain or tenant id containing this application.
69-
* @param secret the authentication secret for the application.
70-
* @param resourceEndpoint the endpoint of the target resource.
71-
* @param environment the Azure environment to authenticate with.
72-
* If null is provided, AzureEnvironment.AZURE will be used.
73-
*/
74-
public ApplicationTokenCredentials(String clientId, String domain, String secret, String resourceEndpoint, AzureEnvironment environment) {
75-
super(null, null); // defer token acquisition
76-
this.clientId = clientId;
77-
this.domain = domain;
78-
this.secret = secret;
79-
this.resourceEndpoint = resourceEndpoint;
80-
if (environment == null) {
81-
this.environment = AzureEnvironment.AZURE;
82-
} else {
83-
this.environment = environment;
84-
}
59+
this.tokens = new HashMap<>();
8560
}
8661

8762
/**
@@ -101,7 +76,9 @@ private enum CredentialSettings {
10176
/** The base URL to the current Azure environment. */
10277
BASE_URL("baseURL"),
10378
/** The URL to Active Directory authentication. */
104-
AUTH_URL("authURL");
79+
AUTH_URL("authURL"),
80+
/** The URL to Active Directory Graph. */
81+
GRAPH_URL("graphURL");
10582

10683
/** The name of the key in the properties file. */
10784
private final String name;
@@ -155,7 +132,7 @@ public static ApplicationTokenCredentials fromFile(File credentialsFile) throws
155132
Properties authSettings = new Properties();
156133
authSettings.put(CredentialSettings.AUTH_URL.toString(), AzureEnvironment.AZURE.getAuthenticationEndpoint());
157134
authSettings.put(CredentialSettings.BASE_URL.toString(), AzureEnvironment.AZURE.getBaseUrl());
158-
authSettings.put(CredentialSettings.MANAGEMENT_URI.toString(), AzureEnvironment.AZURE.getTokenAudience());
135+
authSettings.put(CredentialSettings.MANAGEMENT_URI.toString(), AzureEnvironment.AZURE.getManagementEndpoint());
159136

160137
// Load the credentials from the file
161138
FileInputStream credentialsFileStream = new FileInputStream(credentialsFile);
@@ -168,6 +145,7 @@ public static ApplicationTokenCredentials fromFile(File credentialsFile) throws
168145
final String mgmtUri = authSettings.getProperty(CredentialSettings.MANAGEMENT_URI.toString());
169146
final String authUrl = authSettings.getProperty(CredentialSettings.AUTH_URL.toString());
170147
final String baseUrl = authSettings.getProperty(CredentialSettings.BASE_URL.toString());
148+
final String graphUrl = authSettings.getProperty(CredentialSettings.GRAPH_URL.toString());
171149
final String defaultSubscriptionId = authSettings.getProperty(CredentialSettings.SUBSCRIPTION_ID.toString());
172150

173151
return new ApplicationTokenCredentials(
@@ -177,8 +155,8 @@ public static ApplicationTokenCredentials fromFile(File credentialsFile) throws
177155
new AzureEnvironment(
178156
authUrl,
179157
mgmtUri,
180-
true,
181-
baseUrl)
158+
baseUrl,
159+
graphUrl)
182160
).withDefaultSubscriptionId(defaultSubscriptionId);
183161
}
184162

@@ -196,6 +174,7 @@ public String getClientId() {
196174
*
197175
* @return the tenant or domain the containing the application.
198176
*/
177+
@Override
199178
public String getDomain() {
200179
return domain;
201180
}
@@ -209,42 +188,40 @@ public String getSecret() {
209188
return secret;
210189
}
211190

212-
/**
213-
* Gets the Azure environment to authenticate with.
214-
*
215-
* @return the Azure environment to authenticate with.
216-
*/
217-
public AzureEnvironment getEnvironment() {
218-
return environment;
219-
}
220-
221191
@Override
222-
public String getToken() throws IOException {
223-
if (authenticationResult == null
224-
|| authenticationResult.getAccessToken() == null) {
225-
acquireAccessToken();
192+
public String getToken(String resource) throws IOException {
193+
AuthenticationResult authenticationResult = tokens.get(resource);
194+
if (authenticationResult == null || authenticationResult.getExpiresOnDate().before(new Date())) {
195+
authenticationResult = acquireAccessToken(resource);
226196
}
227197
return authenticationResult.getAccessToken();
228198
}
229199

230200
@Override
231-
public void refreshToken() throws IOException {
232-
acquireAccessToken();
201+
public AzureEnvironment getEnvironment() {
202+
return this.environment;
233203
}
234204

235-
private void acquireAccessToken() throws IOException {
205+
private AuthenticationResult acquireAccessToken(String resource) throws IOException {
236206
String authorityUrl = this.getEnvironment().getAuthenticationEndpoint() + this.getDomain();
237207
ExecutorService executor = Executors.newSingleThreadExecutor();
238208
AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), executor);
239209
try {
240-
authenticationResult = context.acquireToken(
241-
this.resourceEndpoint,
210+
AuthenticationResult result = context.acquireToken(
211+
resource,
242212
new ClientCredential(this.getClientId(), this.getSecret()),
243213
null).get();
214+
tokens.put(resource, result);
215+
return result;
244216
} catch (Exception e) {
245217
throw new IOException(e.getMessage(), e);
246218
} finally {
247219
executor.shutdown();
248220
}
249221
}
222+
223+
@Override
224+
public void applyCredentialsFilter(OkHttpClient.Builder clientBuilder) {
225+
clientBuilder.interceptors().add(new AzureTokenCredentialsInterceptor(this));
226+
}
250227
}

azure-client-authentication/src/main/java/com/microsoft/azure/credentials/UserTokenCredentials.java

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@
1111
import com.microsoft.aad.adal4j.AuthenticationResult;
1212
import com.microsoft.azure.AzureEnvironment;
1313
import com.microsoft.rest.credentials.TokenCredentials;
14+
import okhttp3.OkHttpClient;
1415

1516
import java.io.IOException;
1617
import java.util.Date;
18+
import java.util.HashMap;
19+
import java.util.Map;
1720
import java.util.concurrent.ExecutorService;
1821
import java.util.concurrent.Executors;
1922

2023
/**
2124
* Token based credentials for use with a REST Service Client.
2225
*/
23-
public class UserTokenCredentials extends TokenCredentials {
24-
/** The endpoint of the target resource. */
25-
private String resourceEndpoint;
26+
public class UserTokenCredentials extends TokenCredentials implements AzureTokenCredentials {
27+
/** A mapping from resource endpoint to its cached access token. */
28+
private Map<String, AuthenticationResult> tokens;
2629
/** The Active Directory application client id. */
2730
private String clientId;
2831
/** The domain or tenant id containing this application. */
@@ -31,12 +34,8 @@ public class UserTokenCredentials extends TokenCredentials {
3134
private String username;
3235
/** The password for the Organization Id account. */
3336
private String password;
34-
/** The Uri where the user will be redirected after authenticating with AD. */
35-
private String clientRedirectUri;
3637
/** The Azure environment to authenticate with. */
3738
private AzureEnvironment environment;
38-
/** The current authentication result. */
39-
private AuthenticationResult authenticationResult;
4039

4140
/**
4241
* Initializes a new instance of the UserTokenCredentials.
@@ -45,50 +44,17 @@ public class UserTokenCredentials extends TokenCredentials {
4544
* @param domain the domain or tenant id containing this application.
4645
* @param username the user name for the Organization Id account.
4746
* @param password the password for the Organization Id account.
48-
* @param clientRedirectUri the Uri where the user will be redirected after authenticating with AD.
4947
* @param environment the Azure environment to authenticate with.
5048
* If null is provided, AzureEnvironment.AZURE will be used.
5149
*/
52-
public UserTokenCredentials(String clientId, String domain, String username, String password, String clientRedirectUri, AzureEnvironment environment) {
50+
public UserTokenCredentials(String clientId, String domain, String username, String password, AzureEnvironment environment) {
5351
super(null, null); // defer token acquisition
5452
this.clientId = clientId;
5553
this.domain = domain;
5654
this.username = username;
5755
this.password = password;
58-
this.clientRedirectUri = clientRedirectUri;
59-
if (environment == null) {
60-
this.environment = AzureEnvironment.AZURE;
61-
} else {
62-
this.environment = environment;
63-
}
64-
this.resourceEndpoint = this.environment.getTokenAudience();
65-
}
66-
67-
/**
68-
* Initializes a new instance of the UserTokenCredentials.
69-
*
70-
* @param clientId the active directory application client id.
71-
* @param domain the domain or tenant id containing this application.
72-
* @param username the user name for the Organization Id account.
73-
* @param password the password for the Organization Id account.
74-
* @param clientRedirectUri the Uri where the user will be redirected after authenticating with AD.
75-
* @param resourceEndpoint the endpoint of the target resource.
76-
* @param environment the Azure environment to authenticate with.
77-
* If null is provided, AzureEnvironment.AZURE will be used.
78-
*/
79-
public UserTokenCredentials(String clientId, String domain, String username, String password, String clientRedirectUri, String resourceEndpoint, AzureEnvironment environment) {
80-
super(null, null); // defer token acquisition
81-
this.clientId = clientId;
82-
this.domain = domain;
83-
this.username = username;
84-
this.password = password;
85-
this.clientRedirectUri = clientRedirectUri;
86-
this.resourceEndpoint = resourceEndpoint;
87-
if (environment == null) {
88-
this.environment = AzureEnvironment.AZURE;
89-
} else {
90-
this.environment = environment;
91-
}
56+
this.environment = environment;
57+
this.tokens = new HashMap<>();
9258
}
9359

9460
/**
@@ -105,6 +71,7 @@ public String getClientId() {
10571
*
10672
* @return the tenant or domain the containing the application.
10773
*/
74+
@Override
10875
public String getDomain() {
10976
return domain;
11077
}
@@ -127,13 +94,13 @@ public String getPassword() {
12794
return password;
12895
}
12996

130-
/**
131-
* Gets the Uri where the user will be redirected after authenticating with AD.
132-
*
133-
* @return the redirecting Uri.
134-
*/
135-
public String getClientRedirectUri() {
136-
return clientRedirectUri;
97+
@Override
98+
public String getToken(String resource) throws IOException {
99+
AuthenticationResult authenticationResult = tokens.get(resource);
100+
if (authenticationResult == null || authenticationResult.getExpiresOnDate().before(new Date())) {
101+
authenticationResult = acquireAccessToken(resource);
102+
}
103+
return authenticationResult.getAccessToken();
137104
}
138105

139106
/**
@@ -145,50 +112,47 @@ public AzureEnvironment getEnvironment() {
145112
return environment;
146113
}
147114

148-
@Override
149-
public String getToken() throws IOException {
150-
if (authenticationResult != null
151-
&& authenticationResult.getExpiresOnDate().before(new Date())) {
152-
acquireAccessTokenFromRefreshToken();
153-
} else {
154-
acquireAccessToken();
155-
}
156-
return authenticationResult.getAccessToken();
157-
}
158-
159-
@Override
160-
public void refreshToken() throws IOException {
161-
acquireAccessToken();
162-
}
163-
164-
private void acquireAccessToken() throws IOException {
115+
private AuthenticationResult acquireAccessToken(String resource) throws IOException {
165116
String authorityUrl = this.getEnvironment().getAuthenticationEndpoint() + this.getDomain();
166-
AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), Executors.newSingleThreadExecutor());
117+
ExecutorService executor = Executors.newSingleThreadExecutor();
118+
AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), executor);
167119
try {
168-
authenticationResult = context.acquireToken(
169-
this.resourceEndpoint,
120+
AuthenticationResult result = context.acquireToken(
121+
resource,
170122
this.getClientId(),
171123
this.getUsername(),
172124
this.getPassword(),
173125
null).get();
126+
tokens.put(resource, result);
127+
return result;
174128
} catch (Exception e) {
175129
throw new IOException(e.getMessage(), e);
130+
} finally {
131+
executor.shutdown();
176132
}
177133
}
178134

179-
private void acquireAccessTokenFromRefreshToken() throws IOException {
135+
// Refresh tokens are currently not used since we don't know if the refresh token has expired
136+
private AuthenticationResult acquireAccessTokenFromRefreshToken(String resource) throws IOException {
180137
String authorityUrl = this.getEnvironment().getAuthenticationEndpoint() + this.getDomain();
181138
ExecutorService executor = Executors.newSingleThreadExecutor();
182139
AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), executor);
183140
try {
184-
authenticationResult = context.acquireTokenByRefreshToken(
185-
authenticationResult.getRefreshToken(),
141+
AuthenticationResult result = context.acquireTokenByRefreshToken(
142+
tokens.get(resource).getRefreshToken(),
186143
this.getClientId(),
187144
null, null).get();
145+
tokens.put(resource, result);
146+
return result;
188147
} catch (Exception e) {
189148
throw new IOException(e.getMessage(), e);
190149
} finally {
191150
executor.shutdown();
192151
}
193152
}
153+
154+
@Override
155+
public void applyCredentialsFilter(OkHttpClient.Builder clientBuilder) {
156+
clientBuilder.interceptors().add(new AzureTokenCredentialsInterceptor(this));
157+
}
194158
}

azure-client-authentication/src/test/java/com/microsoft/azure/credentials/UserTokenCredentialsTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public class UserTokenCredentialsTests {
2121
"domain",
2222
"username",
2323
"password",
24-
"redirect",
2524
AzureEnvironment.AZURE
2625
);
2726

@@ -36,8 +35,8 @@ public void testAcquireToken() throws Exception {
3635
public static class MockUserTokenCredentials extends UserTokenCredentials {
3736
private AuthenticationResult authenticationResult;
3837

39-
public MockUserTokenCredentials(String clientId, String domain, String username, String password, String clientRedirectUri, AzureEnvironment environment) {
40-
super(clientId, domain, username, password, clientRedirectUri, environment);
38+
public MockUserTokenCredentials(String clientId, String domain, String username, String password, AzureEnvironment environment) {
39+
super(clientId, domain, username, password, environment);
4140
}
4241

4342
@Override

0 commit comments

Comments
 (0)