9
9
import com .azure .core .util .Configuration ;
10
10
import com .azure .core .util .CoreUtils ;
11
11
import com .azure .core .util .logging .ClientLogger ;
12
- import com .azure .identity .implementation .IdentityClient ;
13
- import com .azure .identity .implementation .IdentityClientBuilder ;
14
12
import com .azure .identity .implementation .IdentityClientOptions ;
15
- import com .azure .identity .implementation .IdentitySyncClient ;
16
13
import com .azure .identity .implementation .util .LoggingUtil ;
17
14
import com .azure .identity .implementation .util .ValidationUtil ;
18
15
import reactor .core .publisher .Mono ;
19
16
17
+ import java .io .IOException ;
18
+ import java .nio .charset .StandardCharsets ;
19
+ import java .nio .file .Files ;
20
+ import java .nio .file .Paths ;
21
+
20
22
import static com .azure .identity .ManagedIdentityCredential .AZURE_FEDERATED_TOKEN_FILE ;
21
23
22
24
/**
54
56
*/
55
57
public class WorkloadIdentityCredential implements TokenCredential {
56
58
private static final ClientLogger LOGGER = new ClientLogger (WorkloadIdentityCredential .class );
57
- private final IdentityClient identityClient ;
58
- private final IdentitySyncClient identitySyncClient ;
59
+ private final ClientAssertionCredential clientAssertionCredential ;
59
60
private final IdentityClientOptions identityClientOptions ;
61
+ private final String clientId ;
60
62
61
63
/**
62
64
* WorkloadIdentityCredential supports Azure workload identity on Kubernetes.
@@ -71,7 +73,7 @@ public class WorkloadIdentityCredential implements TokenCredential {
71
73
ValidationUtil .validateTenantIdCharacterRange (tenantId , LOGGER );
72
74
73
75
Configuration configuration = identityClientOptions .getConfiguration () == null
74
- ? Configuration .getGlobalConfiguration (). clone ()
76
+ ? Configuration .getGlobalConfiguration ()
75
77
: identityClientOptions .getConfiguration ();
76
78
77
79
String tenantIdInput
@@ -88,44 +90,66 @@ public class WorkloadIdentityCredential implements TokenCredential {
88
90
|| CoreUtils .isNullOrEmpty (federatedTokenFilePathInput )
89
91
|| CoreUtils .isNullOrEmpty (clientIdInput )
90
92
|| CoreUtils .isNullOrEmpty (identityClientOptions .getAuthorityHost ()))) {
91
- IdentityClientBuilder builder = new IdentityClientBuilder (). clientAssertionPath ( federatedTokenFilePathInput )
92
- . clientId ( clientIdInput )
93
+
94
+ ClientAssertionCredentialBuilder builder = new ClientAssertionCredentialBuilder ( )
93
95
.tenantId (tenantIdInput )
94
- .identityClientOptions (identityClientOptions );
95
- identityClient = builder .build ();
96
- identitySyncClient = builder .buildSyncClient ();
96
+ .clientId (clientIdInput )
97
+ .clientAssertion (() -> readFederatedTokenFromFile (federatedTokenFilePathInput ));
98
+ builder .authorityHost (identityClientOptions .getAuthorityHost ())
99
+ .httpClient (identityClientOptions .getHttpClient ())
100
+ .maxRetry (identityClientOptions .getMaxRetry ())
101
+ .retryTimeout (identityClientOptions .getRetryTimeout ());
102
+
103
+ if (identityClientOptions .getAdditionallyAllowedTenants () != null ) {
104
+ builder .additionallyAllowedTenants (identityClientOptions .getAdditionallyAllowedTenants ().toArray (new String [0 ]));
105
+ }
106
+
107
+ clientAssertionCredential = builder .build ();
108
+ this .clientId = clientIdInput ;
97
109
} else {
98
- identityClient = null ;
99
- identitySyncClient = null ;
110
+ clientAssertionCredential = null ;
111
+ this . clientId = null ;
100
112
}
101
113
this .identityClientOptions = identityClientOptions ;
102
114
}
103
115
104
116
@ Override
105
117
public Mono <AccessToken > getToken (TokenRequestContext request ) {
106
- if (identityClient == null ) {
118
+ if (clientAssertionCredential == null ) {
107
119
return Mono .error (LoggingUtil .logCredentialUnavailableException (LOGGER , identityClientOptions ,
108
120
new CredentialUnavailableException ("WorkloadIdentityCredential"
109
121
+ " authentication unavailable. The workload options are not fully configured. See the troubleshooting"
110
122
+ " guide for more information."
111
123
+ " https://aka.ms/azsdk/java/identity/workloadidentitycredential/troubleshoot" )));
112
124
}
113
- return identityClient . authenticateWithWorkloadIdentityConfidentialClient (request );
125
+ return clientAssertionCredential . getToken (request );
114
126
}
115
127
116
128
@ Override
117
129
public AccessToken getTokenSync (TokenRequestContext request ) {
118
- if (identitySyncClient == null ) {
130
+ if (clientAssertionCredential == null ) {
119
131
throw LoggingUtil .logCredentialUnavailableException (LOGGER , identityClientOptions ,
120
132
new CredentialUnavailableException ("WorkloadIdentityCredential"
121
133
+ " authentication unavailable. The workload options are not fully configured. See the troubleshooting"
122
134
+ " guide for more information."
123
135
+ " https://aka.ms/azsdk/java/identity/workloadidentitycredential/troubleshoot" ));
124
136
}
125
- return identitySyncClient . authenticateWithWorkloadIdentityConfidentialClient (request );
137
+ return clientAssertionCredential . getTokenSync (request );
126
138
}
127
139
128
140
String getClientId () {
129
- return this .identityClient .getClientId ();
141
+ return this .clientId ;
142
+ }
143
+
144
+ /**
145
+ * Reads the federated token from the specified file path.
146
+ * This token will be used as a client assertion for authentication.
147
+ */
148
+ private String readFederatedTokenFromFile (String filePath ) {
149
+ try {
150
+ return Files .readString (Paths .get (filePath ), StandardCharsets .UTF_8 ).trim ();
151
+ } catch (IOException e ) {
152
+ throw LOGGER .logExceptionAsError (new RuntimeException ("Failed to read federated token from file: " + filePath , e ));
153
+ }
130
154
}
131
155
}
0 commit comments