AzureCredentials.java
/*
* Copyright 2026 Emmanuel Bourg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.jsign.jca;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Azure API credentials
*
* @since 8.0
*/
public class AzureCredentials {
private String endpoint = "https://login.microsoftonline.com";
/** The Microsoft Entra tenant ID */
private String tenantId;
/** The application ID registered in the tenant */
private String clientId;
/** The secret of the application */
private String clientSecret;
/** The access token */
private String token;
/**
* Creates the Azure credentials from either an Azure API access token, for example one obtained with
* the Azure CLI (<tt>az account get-access-token --resource https://vault.azure.net</tt>), or the
* concatenated parameters (<tt>tenantId|clientId|clientSecret</tt>).
*
* @param credentials the Azure API access token, or <tt>tenantId|clientId|clientSecret</tt>
* @throws IllegalArgumentException if the credentials are malformed
*/
public AzureCredentials(String credentials) {
String[] elements = credentials.split("\\|", 3);
if (elements.length == 1) {
token = credentials;
} else if (elements.length == 3) {
tenantId = elements[0];
clientId = elements[1];
clientSecret = elements[2];
} else {
throw new IllegalArgumentException("Invalid Azure credentials, <tenantId>|<clientId>|<clientSecret> expected");
}
}
/**
* Creates the Azure credentials from the specified parameters.
*
* @param tenantId The Microsoft Entra tenant ID (<tt>AZURE_TENANT_ID</tt>)
* @param clientId The application ID registered in the tenant (<tt>AZURE_CLIENT_ID</tt>)
* @param clientSecret The secret of the application (<tt>AZURE_CLIENT_SECRET</tt>)
*/
public AzureCredentials(String tenantId, String clientId, String clientSecret) {
this.tenantId = tenantId;
this.clientId = clientId;
this.clientSecret = clientSecret;
}
void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
String getTenantId() {
return tenantId;
}
String getClientId() {
return clientId;
}
String getClientSecret() {
return clientSecret;
}
/**
* Returns the access token for the specified resource.
*
* @param resource the resource the access token is requested for (for example <tt>https://vault.azure.net</tt>)
*/
public String getAccessToken(String resource) throws IOException {
if (token == null) {
Map<String, String> request = new LinkedHashMap<>();
request.put("grant_type", "client_credentials");
request.put("client_id", clientId);
request.put("client_secret", clientSecret);
request.put("scope", resource + "/.default");
RESTClient client = new RESTClient(endpoint + "/" + tenantId)
.errorHandler(response -> response.get("error") + ": " + response.get("error_description"));
Map<String, ?> response = client.post("/oauth2/v2.0/token", request);
token = (String) response.get("access_token");
}
return token;
}
/**
* Returns the credentials defined by the environment variables <tt>AZURE_TENANT_ID</tt>,
* <tt>AZURE_CLIENT_ID</tt> and <tt>AZURE_CLIENT_SECRET</tt>.
*
* @throws IllegalArgumentException if one of the required variables is missing
* @see <a href="https://learn.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential">EnvironmentCredential Class</a>
*/
public static AzureCredentials getDefault() {
List<String> missing = new ArrayList<>(Arrays.asList("AZURE_TENANT_ID", "AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET"));
missing.removeIf(variable -> getenv(variable) != null);
if (!missing.isEmpty()) {
throw new IllegalArgumentException("Azure credentials are missing from the environment variables: " + String.join(", ", missing));
}
return new AzureCredentials(getenv("AZURE_TENANT_ID"), getenv("AZURE_CLIENT_ID"), getenv("AZURE_CLIENT_SECRET"));
}
static String getenv(String name) {
return System.getenv(name);
}
}