7
7
import com .azure .core .credential .TokenRequestContext ;
8
8
import com .azure .core .test .utils .TestConfigurationSource ;
9
9
import com .azure .core .util .Configuration ;
10
- import com .azure .identity .implementation .IdentityClient ;
11
- import com .azure .identity .implementation .IdentitySyncClient ;
12
10
import com .azure .identity .util .TestUtils ;
13
11
import org .junit .jupiter .api .Assertions ;
14
12
import org .junit .jupiter .api .Test ;
13
+ import org .junit .jupiter .api .io .TempDir ;
15
14
import org .mockito .MockedConstruction ;
15
+
16
+ import reactor .core .publisher .Mono ;
16
17
import reactor .test .StepVerifier ;
17
18
19
+ import java .io .IOException ;
20
+ import java .nio .file .Files ;
21
+ import java .nio .file .Path ;
18
22
import java .time .OffsetDateTime ;
19
23
import java .time .ZoneOffset ;
20
24
import java .util .UUID ;
21
25
22
26
import static org .junit .jupiter .api .Assertions .assertNotNull ;
23
27
import static org .junit .jupiter .api .Assertions .assertTrue ;
28
+ import static org .mockito .ArgumentMatchers .any ;
24
29
import static org .mockito .Mockito .mockConstruction ;
25
30
import static org .mockito .Mockito .when ;
26
31
@@ -29,65 +34,71 @@ public class WorkloadIdentityCredentialTest {
29
34
private static final String CLIENT_ID = UUID .randomUUID ().toString ();
30
35
31
36
@ Test
32
- public void testWorkloadIdentityFlow () {
37
+ public void testWorkloadIdentityFlow (@ TempDir Path tempDir ) throws IOException {
33
38
// setup
34
39
String endpoint = "https://localhost" ;
35
40
String token1 = "token1" ;
36
- TokenRequestContext request1 = new TokenRequestContext ().addScopes ("https://management.azure.com" );
41
+ TokenRequestContext request1 = new TokenRequestContext ().addScopes ("https://management.azure.com/.default " );
37
42
OffsetDateTime expiresAt = OffsetDateTime .now (ZoneOffset .UTC ).plusHours (1 );
38
43
Configuration configuration = TestUtils .createTestConfiguration (
39
44
new TestConfigurationSource ().put (Configuration .PROPERTY_AZURE_AUTHORITY_HOST , endpoint ));
40
45
46
+ // Create a temporary token file
47
+ Path tokenFile = tempDir .resolve ("token.txt" );
48
+ Files .write (tokenFile , "dummy-token" .getBytes ());
49
+
41
50
// mock
42
- try (MockedConstruction <IdentityClient > identityClientMock
43
- = mockConstruction (IdentityClient .class , (identityClient , context ) -> {
44
- when (identityClient . authenticateWithWorkloadIdentityConfidentialClient ( request1 ))
51
+ try (MockedConstruction <ClientAssertionCredential > clientAssertionMock
52
+ = mockConstruction (ClientAssertionCredential .class , (clientAssertion , context ) -> {
53
+ when (clientAssertion . getToken ( any ( TokenRequestContext . class ) ))
45
54
.thenReturn (TestUtils .getMockAccessToken (token1 , expiresAt ));
46
55
})) {
47
56
// test
48
57
WorkloadIdentityCredential credential = new WorkloadIdentityCredentialBuilder ().tenantId ("dummy-tenantid" )
49
- .clientId ("dummy-clientid" )
50
- .tokenFilePath ("dummy-path" )
51
- .configuration (configuration )
52
58
.clientId (CLIENT_ID )
59
+ .tokenFilePath (tokenFile .toString ())
60
+ .configuration (configuration )
53
61
.build ();
54
62
StepVerifier .create (credential .getToken (request1 ))
55
63
.expectNextMatches (token -> token1 .equals (token .getToken ())
56
64
&& expiresAt .getSecond () == token .getExpiresAt ().getSecond ())
57
65
.verifyComplete ();
58
- assertNotNull (identityClientMock );
66
+ assertNotNull (clientAssertionMock );
59
67
}
60
68
}
61
69
62
70
@ Test
63
- public void testWorkloadIdentityFlowSync () {
71
+ public void testWorkloadIdentityFlowSync (@ TempDir Path tempDir ) throws IOException {
64
72
// setup
65
73
String endpoint = "https://localhost" ;
66
74
String token1 = "token1" ;
67
- TokenRequestContext request1 = new TokenRequestContext ().addScopes ("https://management.azure.com" );
75
+ TokenRequestContext request1 = new TokenRequestContext ().addScopes ("https://management.azure.com/.default " );
68
76
OffsetDateTime expiresAt = OffsetDateTime .now (ZoneOffset .UTC ).plusHours (1 );
69
77
Configuration configuration = TestUtils .createTestConfiguration (
70
78
new TestConfigurationSource ().put (Configuration .PROPERTY_AZURE_AUTHORITY_HOST , endpoint ));
71
79
80
+ // Create a temporary token file
81
+ Path tokenFile = tempDir .resolve ("token.txt" );
82
+ Files .write (tokenFile , "dummy-token" .getBytes ());
83
+
72
84
// mock
73
- try (MockedConstruction <IdentitySyncClient > identityClientMock
74
- = mockConstruction (IdentitySyncClient .class , (identityClient , context ) -> {
75
- when (identityClient . authenticateWithWorkloadIdentityConfidentialClient ( request1 ))
85
+ try (MockedConstruction <ClientAssertionCredential > clientAssertionMock
86
+ = mockConstruction (ClientAssertionCredential .class , (clientAssertion , context ) -> {
87
+ when (clientAssertion . getTokenSync ( any ( TokenRequestContext . class ) ))
76
88
.thenReturn (TestUtils .getMockAccessTokenSync (token1 , expiresAt ));
77
89
})) {
78
90
// test
79
91
WorkloadIdentityCredential credential = new WorkloadIdentityCredentialBuilder ().tenantId ("dummy-tenantid" )
80
- .clientId ("dummy-clientid" )
81
- .tokenFilePath ("dummy-path" )
82
- .configuration (configuration )
83
92
.clientId (CLIENT_ID )
93
+ .tokenFilePath (tokenFile .toString ())
94
+ .configuration (configuration )
84
95
.build ();
85
96
86
97
AccessToken token = credential .getTokenSync (request1 );
87
98
88
99
assertTrue (token1 .equals (token .getToken ()));
89
100
assertTrue (expiresAt .getSecond () == token .getExpiresAt ().getSecond ());
90
- assertNotNull (identityClientMock );
101
+ assertNotNull (clientAssertionMock );
91
102
}
92
103
}
93
104
@@ -135,4 +146,47 @@ public void testWorkloadIdentityFlowFailureNoTokenPath() {
135
146
.clientId ("client-id" )
136
147
.build ());
137
148
}
138
- }
149
+
150
+ @ Test
151
+ public void testGetClientId (@ TempDir Path tempDir ) throws IOException {
152
+ // setup
153
+ String endpoint = "https://localhost" ;
154
+ Configuration configuration = TestUtils .createTestConfiguration (
155
+ new TestConfigurationSource ().put (Configuration .PROPERTY_AZURE_AUTHORITY_HOST , endpoint ));
156
+
157
+ // test
158
+ WorkloadIdentityCredential credential = new WorkloadIdentityCredentialBuilder ().tenantId ("dummy-tenantid" )
159
+ .clientId (CLIENT_ID )
160
+ .tokenFilePath ("dummy-path" )
161
+ .configuration (configuration )
162
+ .build ();
163
+
164
+ Assertions .assertEquals (CLIENT_ID , credential .getClientId ());
165
+ }
166
+
167
+ @ Test
168
+ public void testFileReadingError (@ TempDir Path tempDir ) {
169
+ // setup
170
+ String endpoint = "https://localhost" ;
171
+ Configuration configuration = TestUtils .createTestConfiguration (
172
+ new TestConfigurationSource ().put (Configuration .PROPERTY_AZURE_AUTHORITY_HOST , endpoint ));
173
+ TokenRequestContext request = new TokenRequestContext ().addScopes ("https://management.azure.com/.default" );
174
+
175
+ String nonExistentFile = tempDir .resolve ("non-existent-file.txt" ).toString ();
176
+
177
+ WorkloadIdentityCredential credential = new WorkloadIdentityCredentialBuilder ()
178
+ .tenantId ("dummy-tenantid" )
179
+ .clientId (CLIENT_ID )
180
+ .tokenFilePath (nonExistentFile )
181
+ .configuration (configuration )
182
+ .build ();
183
+
184
+ StepVerifier .create (credential .getToken (request ))
185
+ .expectErrorSatisfies (error -> {
186
+ assertTrue (error instanceof RuntimeException );
187
+ assertTrue (error .getMessage ().contains ("Failed to read federated token from file" ));
188
+ assertTrue (error .getCause () instanceof IOException ); // Original IOException from Files.readAllBytes
189
+ })
190
+ .verify ();
191
+ }
192
+ }
0 commit comments