11
11
import com .microsoft .aad .adal4j .AuthenticationResult ;
12
12
import com .microsoft .azure .AzureEnvironment ;
13
13
import com .microsoft .rest .credentials .TokenCredentials ;
14
+ import okhttp3 .OkHttpClient ;
14
15
15
16
import java .io .IOException ;
16
17
import java .util .Date ;
18
+ import java .util .HashMap ;
19
+ import java .util .Map ;
17
20
import java .util .concurrent .ExecutorService ;
18
21
import java .util .concurrent .Executors ;
19
22
20
23
/**
21
24
* Token based credentials for use with a REST Service Client.
22
25
*/
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 ;
26
29
/** The Active Directory application client id. */
27
30
private String clientId ;
28
31
/** The domain or tenant id containing this application. */
@@ -31,12 +34,8 @@ public class UserTokenCredentials extends TokenCredentials {
31
34
private String username ;
32
35
/** The password for the Organization Id account. */
33
36
private String password ;
34
- /** The Uri where the user will be redirected after authenticating with AD. */
35
- private String clientRedirectUri ;
36
37
/** The Azure environment to authenticate with. */
37
38
private AzureEnvironment environment ;
38
- /** The current authentication result. */
39
- private AuthenticationResult authenticationResult ;
40
39
41
40
/**
42
41
* Initializes a new instance of the UserTokenCredentials.
@@ -45,50 +44,17 @@ public class UserTokenCredentials extends TokenCredentials {
45
44
* @param domain the domain or tenant id containing this application.
46
45
* @param username the user name for the Organization Id account.
47
46
* @param password the password for the Organization Id account.
48
- * @param clientRedirectUri the Uri where the user will be redirected after authenticating with AD.
49
47
* @param environment the Azure environment to authenticate with.
50
48
* If null is provided, AzureEnvironment.AZURE will be used.
51
49
*/
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 ) {
53
51
super (null , null ); // defer token acquisition
54
52
this .clientId = clientId ;
55
53
this .domain = domain ;
56
54
this .username = username ;
57
55
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 <>();
92
58
}
93
59
94
60
/**
@@ -105,6 +71,7 @@ public String getClientId() {
105
71
*
106
72
* @return the tenant or domain the containing the application.
107
73
*/
74
+ @ Override
108
75
public String getDomain () {
109
76
return domain ;
110
77
}
@@ -127,13 +94,13 @@ public String getPassword() {
127
94
return password ;
128
95
}
129
96
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 () ;
137
104
}
138
105
139
106
/**
@@ -145,50 +112,47 @@ public AzureEnvironment getEnvironment() {
145
112
return environment ;
146
113
}
147
114
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 {
165
116
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 );
167
119
try {
168
- authenticationResult = context .acquireToken (
169
- this . resourceEndpoint ,
120
+ AuthenticationResult result = context .acquireToken (
121
+ resource ,
170
122
this .getClientId (),
171
123
this .getUsername (),
172
124
this .getPassword (),
173
125
null ).get ();
126
+ tokens .put (resource , result );
127
+ return result ;
174
128
} catch (Exception e ) {
175
129
throw new IOException (e .getMessage (), e );
130
+ } finally {
131
+ executor .shutdown ();
176
132
}
177
133
}
178
134
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 {
180
137
String authorityUrl = this .getEnvironment ().getAuthenticationEndpoint () + this .getDomain ();
181
138
ExecutorService executor = Executors .newSingleThreadExecutor ();
182
139
AuthenticationContext context = new AuthenticationContext (authorityUrl , this .getEnvironment ().isValidateAuthority (), executor );
183
140
try {
184
- authenticationResult = context .acquireTokenByRefreshToken (
185
- authenticationResult .getRefreshToken (),
141
+ AuthenticationResult result = context .acquireTokenByRefreshToken (
142
+ tokens . get ( resource ) .getRefreshToken (),
186
143
this .getClientId (),
187
144
null , null ).get ();
145
+ tokens .put (resource , result );
146
+ return result ;
188
147
} catch (Exception e ) {
189
148
throw new IOException (e .getMessage (), e );
190
149
} finally {
191
150
executor .shutdown ();
192
151
}
193
152
}
153
+
154
+ @ Override
155
+ public void applyCredentialsFilter (OkHttpClient .Builder clientBuilder ) {
156
+ clientBuilder .interceptors ().add (new AzureTokenCredentialsInterceptor (this ));
157
+ }
194
158
}
0 commit comments