docs
0
# Advanced Authentication Flows
1
2
Advanced authentication flows support specialized scenarios including on-behalf-of delegation, workload identity federation, and Azure Pipelines service connections. These flows enable complex authentication patterns for service-to-service communication and cloud-native applications.
3
4
## On-Behalf-Of (OBO) Flow
5
6
The on-behalf-of flow enables a service to call another service on behalf of a user, using a JWT assertion from the original user authentication.
7
8
```java
9
import com.azure.identity.OnBehalfOfCredential;
10
import com.azure.identity.OnBehalfOfCredentialBuilder;
11
12
// Using client secret
13
TokenCredential oboCredential = new OnBehalfOfCredentialBuilder()
14
.tenantId("tenant-id")
15
.clientId("middle-tier-service-client-id")
16
.clientSecret("client-secret")
17
.userAssertion("jwt-token-from-original-user-auth")
18
.build();
19
20
// Using client certificate
21
TokenCredential oboCertCredential = new OnBehalfOfCredentialBuilder()
22
.tenantId("tenant-id")
23
.clientId("middle-tier-service-client-id")
24
.pfxCertificate("path/to/certificate.pfx", "certificate-password")
25
.userAssertion("jwt-token-from-original-user-auth")
26
.build();
27
```
28
29
## Workload Identity Federation
30
31
Workload identity enables applications running in external identity systems (like Kubernetes) to authenticate to Azure without storing secrets.
32
33
```java
34
import com.azure.identity.WorkloadIdentityCredential;
35
import com.azure.identity.WorkloadIdentityCredentialBuilder;
36
37
// Basic workload identity (reads from environment variables)
38
TokenCredential credential = new WorkloadIdentityCredentialBuilder().build();
39
40
// Manual configuration
41
TokenCredential manualCredential = new WorkloadIdentityCredentialBuilder()
42
.tenantId("tenant-id")
43
.clientId("client-id")
44
.tokenFilePath("/var/run/secrets/azure/tokens/azure-identity-token")
45
.build();
46
```
47
48
## Azure Pipelines Service Connection
49
50
Authenticate using Azure Pipelines service connections for CI/CD scenarios.
51
52
```java
53
import com.azure.identity.AzurePipelinesCredential;
54
import com.azure.identity.AzurePipelinesCredentialBuilder;
55
56
// Azure Pipelines credential
57
TokenCredential credential = new AzurePipelinesCredentialBuilder()
58
.tenantId("tenant-id")
59
.clientId("service-connection-client-id")
60
.serviceConnectionId("service-connection-id")
61
.systemAccessToken(System.getenv("SYSTEM_ACCESSTOKEN")) // From pipeline variable
62
.build();
63
```
64
65
## Environment Variables for Advanced Flows
66
67
### Workload Identity
68
- **AZURE_CLIENT_ID** - Client ID of the managed identity or service principal
69
- **AZURE_TENANT_ID** - Azure tenant ID
70
- **AZURE_FEDERATED_TOKEN_FILE** - Path to the federated token file
71
- **AZURE_AUTHORITY_HOST** - Microsoft Entra ID authority host
72
73
### Azure Pipelines
74
- **SYSTEM_ACCESSTOKEN** - System access token from Azure Pipelines
75
- **AZURE_CLIENT_ID** - Client ID of the service connection
76
- **AZURE_TENANT_ID** - Tenant ID
77
- **AZURESUBSCRIPTION_SERVICE_CONNECTION_ID** - Service connection ID
78
79
## Advanced OBO Scenarios
80
81
```java
82
// OBO with additional scopes
83
TokenCredential oboCredential = new OnBehalfOfCredentialBuilder()
84
.tenantId("tenant-id")
85
.clientId("client-id")
86
.clientSecret("client-secret")
87
.userAssertion("user-jwt-token")
88
.build();
89
90
// Get token for downstream service
91
AccessToken downstreamToken = oboCredential.getTokenSync(
92
new TokenRequestContext()
93
.addScopes("api://downstream-service/.default")
94
.setTenantId("downstream-tenant-id")
95
);
96
```
97
98
## Kubernetes Workload Identity Setup
99
100
For Azure Kubernetes Service (AKS) with workload identity:
101
102
```yaml
103
# Kubernetes ServiceAccount with workload identity annotation
104
apiVersion: v1
105
kind: ServiceAccount
106
metadata:
107
name: my-service-account
108
namespace: default
109
annotations:
110
azure.workload.identity/client-id: "client-id-of-user-assigned-managed-identity"
111
---
112
apiVersion: apps/v1
113
kind: Deployment
114
metadata:
115
name: my-application
116
spec:
117
template:
118
metadata:
119
labels:
120
azure.workload.identity/use: "true"
121
spec:
122
serviceAccountName: my-service-account
123
containers:
124
- name: my-app
125
image: my-app-image
126
env:
127
- name: AZURE_CLIENT_ID
128
value: "client-id-of-user-assigned-managed-identity"
129
```
130
131
```java
132
// In the application running in Kubernetes
133
TokenCredential credential = new WorkloadIdentityCredentialBuilder().build();
134
135
// The credential automatically uses the federated token from the pod
136
AccessToken token = credential.getTokenSync(
137
new TokenRequestContext().addScopes("https://graph.microsoft.com/.default")
138
);
139
```
140
141
## Multi-Tenant OBO Flow
142
143
```java
144
// Configure OBO for multi-tenant scenarios
145
TokenCredential oboCredential = new OnBehalfOfCredentialBuilder()
146
.tenantId("primary-tenant-id")
147
.clientId("client-id")
148
.clientSecret("client-secret")
149
.userAssertion("user-jwt-token")
150
.additionallyAllowedTenants("*") // Allow cross-tenant access
151
.build();
152
```
153
154
## Custom Authority Hosts
155
156
```java
157
// Use different authority hosts for sovereign clouds
158
TokenCredential govCloudCredential = new OnBehalfOfCredentialBuilder()
159
.tenantId("tenant-id")
160
.clientId("client-id")
161
.clientSecret("client-secret")
162
.userAssertion("user-jwt-token")
163
.authorityHost(AzureAuthorityHosts.AZURE_GOVERNMENT)
164
.build();
165
```
166
167
## Error Handling
168
169
```java
170
try {
171
OnBehalfOfCredential credential = new OnBehalfOfCredentialBuilder()
172
.tenantId("tenant-id")
173
.clientId("client-id")
174
.clientSecret("client-secret")
175
.userAssertion("user-jwt-token")
176
.build();
177
178
AccessToken token = credential.getTokenSync(
179
new TokenRequestContext().addScopes("api://downstream/.default")
180
);
181
182
System.out.println("OBO authentication successful");
183
184
} catch (ClientAuthenticationException e) {
185
System.err.println("OBO authentication failed: " + e.getMessage());
186
// Common causes:
187
// - Invalid user assertion
188
// - Service principal lacks necessary permissions
189
// - Downstream API not configured for OBO
190
} catch (CredentialUnavailableException e) {
191
System.err.println("OBO credential unavailable: " + e.getMessage());
192
}
193
```
194
195
## API Reference
196
197
```java { .api }
198
class OnBehalfOfCredential implements TokenCredential {
199
Mono<AccessToken> getToken(TokenRequestContext request);
200
AccessToken getTokenSync(TokenRequestContext request);
201
}
202
203
class OnBehalfOfCredentialBuilder extends AadCredentialBuilderBase<OnBehalfOfCredentialBuilder> {
204
OnBehalfOfCredentialBuilder userAssertion(String userAssertion);
205
OnBehalfOfCredentialBuilder clientSecret(String clientSecret);
206
OnBehalfOfCredentialBuilder pfxCertificate(String certificatePath, String clientCertificatePassword);
207
OnBehalfOfCredentialBuilder pemCertificate(String certificatePath);
208
OnBehalfOfCredentialBuilder clientAssertion(Supplier<String> clientAssertionSupplier);
209
OnBehalfOfCredentialBuilder sendCertificateChain(boolean sendCertificateChain);
210
OnBehalfOfCredential build();
211
}
212
213
class WorkloadIdentityCredential implements TokenCredential {
214
Mono<AccessToken> getToken(TokenRequestContext request);
215
AccessToken getTokenSync(TokenRequestContext request);
216
}
217
218
class WorkloadIdentityCredentialBuilder extends AadCredentialBuilderBase<WorkloadIdentityCredentialBuilder> {
219
WorkloadIdentityCredentialBuilder tokenFilePath(String tokenFilePath);
220
WorkloadIdentityCredential build();
221
}
222
223
class AzurePipelinesCredential implements TokenCredential {
224
Mono<AccessToken> getToken(TokenRequestContext request);
225
AccessToken getTokenSync(TokenRequestContext request);
226
}
227
228
class AzurePipelinesCredentialBuilder extends AadCredentialBuilderBase<AzurePipelinesCredentialBuilder> {
229
AzurePipelinesCredentialBuilder systemAccessToken(String systemAccessToken);
230
AzurePipelinesCredentialBuilder serviceConnectionId(String serviceConnectionId);
231
AzurePipelinesCredential build();
232
}
233
```
234
235
## Advanced Configuration
236
237
```java
238
// Configure with detailed options
239
TokenCredential credential = new OnBehalfOfCredentialBuilder()
240
.tenantId("tenant-id")
241
.clientId("client-id")
242
.clientSecret("client-secret")
243
.userAssertion("user-jwt-token")
244
.authorityHost(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD)
245
.disableInstanceDiscovery()
246
.executorService(executorService)
247
.httpClient(httpClient)
248
.maxRetry(3)
249
.build();
250
```
251
252
## Best Practices
253
254
1. **Secure Assertion Handling**: Protect user assertions and never log them
255
2. **Scope Minimization**: Request only the minimum required scopes for downstream services
256
3. **Token Caching**: Advanced credentials automatically handle token caching
257
4. **Permission Configuration**: Ensure proper API permissions are configured for OBO scenarios
258
5. **Workload Identity Setup**: Use workload identity federation instead of storing secrets in containers
259
6. **Service Connection Security**: Protect Azure Pipelines service connection credentials
260
7. **Multi-Tenant Awareness**: Carefully configure tenant access for cross-tenant scenarios
261
8. **Error Handling**: Implement comprehensive error handling for complex authentication flows
262
263
## Security Considerations
264
265
1. **User Assertion Validation**: Validate user assertions before using them in OBO flows
266
2. **Downstream Permissions**: Ensure downstream services are configured to accept OBO tokens
267
3. **Token Lifetime**: Consider token lifetime implications in chained authentication scenarios
268
4. **Audit Logging**: Enable audit logging for advanced authentication flows
269
5. **Network Security**: Secure network communications between services in OBO scenarios