![](/img/trans.png)
[英]java.sql.SQLException when trying to connect to azure database using spring-boot
[英]How to connect to Azure Blob Storage using Service Principal with Java/Spring-Boot
我正在使用 Spring Boot 和 Java 编写一个将文件写入 Azure Blob 存储的应用程序。 如何使用服务主体进行身份验证? 理想情况下,应通过某些属性或外部文件读取 SP 的详细信息。
我一直在翻阅大量的文档和示例,所有这些似乎都不是我想要的。 我见过的大多数示例都使用了我不想使用的存储帐户密钥。
一些示例代码将不胜感激。 正如我所说,我正在努力寻找一个体面的示例(包括如何使用 SP,以及通常如何使用 Java 写入 Azure BLOB 存储),因为似乎有很多不同的方法可以访问分散在各处的存储微软文档。
您可以使用ADAL4J获取令牌,然后使用该令牌写入 Blob。
获取令牌。
public static String getToken() throws Exception { String TENANT_ID = "your tenant id or name, e4c9*-*-*-*-*57fb"; String AUTHORITY = "https://login.microsoftonline.com/" + TENANT_ID; String CLIENT_ID = "your application id, dc17*-*-*-*a5e7"; String CLIENT_SECRET = "the secret, /pG*32"; String RESOURCE = "https://storage.azure.com/"; String ACCESS_TOKEN = null; ExecutorService service = Executors.newFixedThreadPool(1); AuthenticationContext context = null; try { context = new AuthenticationContext(AUTHORITY, false, service); ClientCredential credential = new ClientCredential(CLIENT_ID, CLIENT_SECRET); Future<AuthenticationResult> future = context.acquireToken(RESOURCE, credential, null); ACCESS_TOKEN = future.get().getAccessToken(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } finally { service.shutdown(); } return ACCESS_TOKEN; }
访问 blob。
public static void main(String[] args) throws Exception { String token = getToken(); StorageCredentialsToken credentialsToken = new StorageCredentialsToken("storagetest789", token); CloudBlobClient blobClient = new CloudBlobClient(new URI("https://storagetest789.blob.core.windows.net/"), credentialsToken); CloudBlobContainer blobContainer = blobClient.getContainerReference("pub"); CloudBlockBlob blockBlob = blobContainer.getBlockBlobReference("test.txt"); blockBlob.uploadText("Test!"); }
希望能帮助到你。
我创建了一篇关于使用服务主体将 Spring Boot App 与 Azure 存储帐户连接的文章,您可以参考。
https://medium.com/@iamdeveshkumar/using-azure-blob-storage-with-a-spring-boot-app-6238c137df7
pom.xml
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.12.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.3.1</version>
</dependency>
应用程序属性
app.config.azure.client-id=xxxxxxxxxxx
app.config.azure.client-secret=xxxxxxxxxxx
app.config.azure.tenant-id=xxxxxxxxxxx
app.config.azure.storage-id=xxxxxxxxxxx
app.config.azure.storage-endpoint=https://{STORAGE-ID}.blob.core.windows.net
app.config.azure.storage.container=xxxxxxxxxxx
AzureStorageConfiguration.java
@Data
@Configuration
@Slf4j
public class AzureStorageConfiguration {
private static final Logger logger = LoggerFactory.getLogger(AzureStorageConfiguration.class);
@Value("${app.config.azure.client-id}")
private String clientId;
@Value("${app.config.azure.client-secret}")
private String clientSecret;
@Value("${app.config.azure.tenant-id}")
private String tenantId;
@Value("${app.config.azure.storage-id}")
private String storageId;
@Value("${app.config.azure.storage-endpoint}")
private String storageEndpoint;
@Value("${app.config.azure.storage.container}")
private String storageContainer;
/**
* Blob service client builder blob service client builder.
*
* @return the blob service client builder
*/
@Bean
public BlobServiceClientBuilder blobServiceClientBuilder() {
return new BlobServiceClientBuilder()
.credential(getAzureClientCredentials())
.endpoint(getStorageEndpoint());
}
private ClientSecretCredential getAzureClientCredentials() {
return new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.build();
}
/**
* Gets storage endpoint.
*
* @return the storage endpoint
*/
public String getStorageEndpoint() {
return storageEndpoint.replace("{STORAGE-ID}", storageId);
}
/**
* A util method to upload a file to Azure Storage.
*
* @param blobServiceClientBuilder service client builder
* @return BlobServiceAsyncClient blob service async client
*/
@Bean(name = "blobServiceAsyncClient")
public BlobServiceAsyncClient blobServiceAsyncClient(
BlobServiceClientBuilder blobServiceClientBuilder) {
/*
retryDelay is by default 4ms and maxRetryDelay is by default 120ms
*/
return blobServiceClientBuilder.retryOptions(
new RequestRetryOptions(
RetryPolicyType.EXPONENTIAL,
5,
Duration.ofSeconds(300L),
null,
null,
null)).buildAsyncClient();
}
}
然后,您可以使用BlobServiceAsyncClient为各种 blob 操作创建BlobAsyncClient 。
/**
* Get blob async client blob async client.
*
* @param container the container
* @param blobName the blob name
* @return the blob async client
*/
public BlobAsyncClient getBlobAsyncClient(String container, String blobName) {
BlobContainerAsyncClient blobContainerAsyncClient =
blobServiceAsyncClient.getBlobContainerAsyncClient(container);
return blobContainerAsyncClient.getBlobAsyncClient(blobName);
}
/**
* Upload to azure blob.
*
* @param container the container
* @param blobName the blob name
* @param data the data
*/
public void uploadToAzureBlob(String container, String blobName, byte[] data) {
BlobAsyncClient blobAsyncClient = getBlobAsyncClient(container, blobName);
long blockSize = 2L * 1024L * 1024L; //2MB
blobAsyncClient.upload(covertByteArrayToFlux(data),
getTransferOptions(blockSize), true)
.doOnSuccess(blockBlobItem -> logger.info("Successfully uploaded !!"))
.doOnError(throwable -> logger.error(
"Error occurred while uploading !! Exception:{}",
throwable.getMessage()))
.subscribe();
}
/**
* Covert byte array to flux flux.
*
* @param byteArray the byte array
* @return the flux
*/
public Flux<ByteBuffer> covertByteArrayToFlux(byte[] byteArray) {
return Flux.just(ByteBuffer.wrap(byteArray));
}
/**
* Creating TransferOptions.
*
* @param blockSize represents block size
* @return ParallelTransferOptions transfer options
*/
public ParallelTransferOptions getTransferOptions(long blockSize) {
return new ParallelTransferOptions()
.setBlockSizeLong(blockSize)
.setMaxConcurrency(5)
.setProgressReceiver(
bytesTransferred -> logger.info("Uploading bytes:{}", bytesTransferred));
}
更多细节和代码可以参考我的github repo
https://github.com/kdevesh/azure-storage-spring-boot-app
PS 我正在使用 Blob Client 的异步风格,如果有人想使用它,也可以使用同步风格。
获取访问令牌的另一种方法是使用 MS 身份验证库
该库使用“构建器”来构建机密客户端。 如果您使用该类,它会为您处理刷新令牌并处理缓存
我用Jack Jia的方法,但是不行……我可以拿到token,但是上传的时候,有问题在这里输入图片描述
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.