gpt4 book ai didi

java - 如何使用基于证书的身份验证创建Azure blob并使用java从中下载文件

转载 作者:太空宇宙 更新时间:2023-11-04 09:32:26 29 4
gpt4 key购买 nike

我编写了一个java程序,它连接到我创建的Azure blob存储,并使用下面的程序下载文件内容,但我真正的产品场景是不同的,客户端共享了ThumbPrint、ClientId、AzureKeyVaultUrl、SecretId以及containerName和证书。我的程序在我创建的有试用期的帐户上运行良好。但不明白如何创建具有基于证书的身份验证的帐户,并在使用 java 程序连接时使用该帐户。封装com;

import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.OperationContext;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.*;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.Scanner;

public class ConnectToAzureToExistingContainer {
public static final String storageConnectionString =
"DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy;EndpointSuffix=zzzz";


public static void main( String[] args )
{
CloudStorageAccount storageAccount;
CloudBlobClient blobClient = null;
CloudBlobContainer container=null;
try {
storageAccount = CloudStorageAccount.parse(storageConnectionString);
blobClient = storageAccount.createCloudBlobClient();
container = blobClient.getContainerReference("revenuestream");
CloudBlockBlob blob = container.getBlockBlobReference("revenuestreams.csv");
System.out.println(blob.downloadText());
System.out.println("Done...");
}
catch (StorageException ex){
System.out.println(String.format("Error returned from the service. Http code: %d and error code: %s", ex.getHttpStatusCode(), ex.getErrorCode()));
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}

最佳答案

正如 @Thomas 所说,您可以使用 Azure AD 获取访问 token 来访问您的存储文件。主要机制可以引用this doc 。您需要获取访问 token 才能调用 storage APIs访问您的存储服务。并且您想使用证书来获取此访问 token 来访问存储服务。您可以按照以下步骤操作。

  1. 准备 .cer 证书和 .pfx 证书并将 .cer 上传到 Azure AD 应用: enter image description here

  2. 运行此 ps 来获取 .pfx 文件的 x5t 值,我们在签署 jwt token 时需要它:

$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import("path of your .pfx file","password of your .pfx file",'Exportable')
$x5t = [System.Convert]::ToBase64String($cer.GetCertHash())
$x5t

  • 将.pfx文件转换为.der文件,以便我们可以在Java中轻松使用它:

    1)从 pfx 转换 Pem 文件:

    openssl pkcs12 -in“您的.pfx文件路径”-out“新.pem文件路径”-clcerts

    2)将Pem转换为der,以便java可以轻松读取:

    openssl pkcs8 -topk8 -inform PEM -outform DER -in "pem 文件路径"-out "新 der 文件路径"-nocrypt

  • 请按照以下代码从 Azure AD 获取访问 token :

  • import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.util.Date;
    import java.util.UUID;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import javax.naming.ServiceUnavailableException;
    import com.microsoft.aad.adal4j.AuthenticationContext;
    import com.microsoft.aad.adal4j.AuthenticationResult;
    import com.microsoft.aad.adal4j.ClientAssertion;

    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;

    public class PublicClient {

    private final static String TENANT_ID = "your tanant id";
    private final static String AUTHORITY = "https://login.microsoftonline.com/" + TENANT_ID;
    private final static String CLIENT_ID = "your Azure AD app ID";
    private final static String X5TVALUE_STRING = "x5t value we get from step2 ";
    private final static String DERFILE_PATH_STRING = "der file path";

    public static void main(String args[]) throws Exception {
    // Request access token from AAD
    AuthenticationResult result = getAccessToken();

    System.out.print(result.getAccessToken());

    }

    public static PrivateKey getPrivateKey() throws Exception {
    byte[] keyBytes = Files.readAllBytes(Paths.get(DERFILE_PATH_STRING));
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
    }

    private static AuthenticationResult getAccessToken() throws Exception {
    AuthenticationContext context;
    AuthenticationResult result;
    ExecutorService service = null;
    try {
    service = Executors.newFixedThreadPool(1);
    context = new AuthenticationContext(AUTHORITY, false, service);

    PrivateKey key = getPrivateKey();
    String jwt = Jwts.builder().setHeaderParam("typ", "JWT").setHeaderParam("alg", "RS256")
    .setHeaderParam("x5t",X5TVALUE_STRING).setSubject(CLIENT_ID)
    .setExpiration(new Date(System.currentTimeMillis() + 200000)).setIssuer(CLIENT_ID)
    .setNotBefore(new Date())
    .setAudience("https://login.microsoftonline.com/" + TENANT_ID + "/oauth2/token")
    .setId(UUID.randomUUID().toString()).signWith(SignatureAlgorithm.RS256, key).compact();

    ClientAssertion clientAssertion = new ClientAssertion(jwt);

    Future<AuthenticationResult> future = context.acquireToken("https://storage.azure.com/", clientAssertion,
    null);

    result = future.get();
    } finally {
    service.shutdown();
    }

    if (result == null) {
    throw new ServiceUnavailableException("authentication result was null");
    }
    return result;
    }

    }

    使用此 token ,我们可以调用存储 REST API,请注意,如果您使用 Azure AD 身份验证来访问存储,则请求 header 中需要“x-ms-version: 2017-11-09”: enter image description here

    关于java - 如何使用基于证书的身份验证创建Azure blob并使用java从中下载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56924802/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com