使用令牌通过已注册的应用程序访问 Azure Blob
Accessing Azure Blob via a Registered App Using Tokens
我是 Azure 的新手,我正在努力让一个简单的演示工作。
我正在尝试编写一个访问 blob 的守护进程客户端。访问必须通过已注册的应用程序,我想明确获取访问令牌。
作为热身,我编写了一个使用 blob api 访问 blob 的演示,并且工作正常:
ClientCertificateCredential credentials = new ClientCertificateCredentialBuilder()
.clientId("11518eab-7b5a-493c-8d12-27731fe51341")
.tenantId("4b106bc5-7518-4f86-a259-f5726d124732")
.pemCertificate("/home/william/cert/new/azure.pem")
.build();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.credential(credentials)
.endpoint("https://wemsa.blob.core.windows.net/")
.buildClient();
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient("wemco");
blobContainerClient.getBlobClient("spiral.jpeg")
.downloadToFile("/home/william/blob.jpeg");
以上代码使用我注册的应用程序创建一个 BlobClient
下载我的 blob 文件。这有效的事实表明我的应用程序确实具有访问我的存储容器所需的角色。
我想创建第二个演示来做同样的事情,但我想明确获取访问令牌并使用它来授权对 blob api 的普通 http 请求。到目前为止,这是我制作的:
private static final String TENANT_ID = "4b106bc5-7518-4f86-a259-f5726d124732";
private static final String CLIENT_ID = "11518eab-7b5a-493c-8d12-27731fe51341";
private static final String AUTHORITY = "https://login.microsoftonline.com/" + TENANT_ID;
private static final Set<String> SCOPE = Collections.singleton("api://" + CLIENT_ID + "/.default");
InputStream pkcs12Cert = new FileInputStream("/home/william/cert/new/azure.p12");
String certPwd = "password123";
IClientCredential credential = ClientCredentialFactory.createFromCertificate(pkcs12Cert, certPwd);
ConfidentialClientApplication cca = ConfidentialClientApplication
.builder(CLIENT_ID, credential).authority(AUTHORITY).build();
ClientCredentialParameters parameters = ClientCredentialParameters.builder(SCOPE).build();
IAuthenticationResult result = cca.acquireToken(parameters).join();
String token = result.accessToken();
URI uri = new URI("https://wemsa.blob.core.windows.net/wemco/spiral.jpeg");
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.header("Authorization", "Bearer " + token)
.header("Date", formatNow())
.header("x-ms-version", "2020-06-12")
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode()); // 401 !!!
这使用与第一个演示相同的注册应用。调试告诉我它正在成功获取访问令牌。但是,当我尝试使用它们时,我总是会收到 401 响应。我曾希望第一个演示运行正常,第二个演示也能自动运行 - 但它没有。
- 我想做的事情是否可行?
- 我第二个demo的代码有问题吗?
- 在演示 2 运行之前,我是否需要在 Azure 中进行更多设置?一些 Azure 文档提到创建一个应用程序角色,我试过了,但我不知道如何处理它。
有什么建议吗?
附加信息:这是我在 Azure 中所做的(接受所有默认值):
- 创建存储帐户wemsa
- 在 wemsa
中创建容器 wemco
- 上传(小)文件 'spiral.jpeg' 到容器 wemco
- 创建应用注册wemapp
- 将证书 'azure.crt' 上传到 wemapp
然后我回到容器wemco并且:
- 将角色 'Storage Blob Data Contributor' 授予 wemapp
这足以使演示 1 工作。
通过将范围(即请求的资源)更改为 azure 存储来修复:
private static final Set<String> SCOPE =
Collections.singleton("https://storage.azure.com//.default");
进行此更改后,我可以使用原始帖子中的演示 2 代码下载我的 blob 文件。
我是 Azure 的新手,我正在努力让一个简单的演示工作。
我正在尝试编写一个访问 blob 的守护进程客户端。访问必须通过已注册的应用程序,我想明确获取访问令牌。
作为热身,我编写了一个使用 blob api 访问 blob 的演示,并且工作正常:
ClientCertificateCredential credentials = new ClientCertificateCredentialBuilder()
.clientId("11518eab-7b5a-493c-8d12-27731fe51341")
.tenantId("4b106bc5-7518-4f86-a259-f5726d124732")
.pemCertificate("/home/william/cert/new/azure.pem")
.build();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.credential(credentials)
.endpoint("https://wemsa.blob.core.windows.net/")
.buildClient();
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient("wemco");
blobContainerClient.getBlobClient("spiral.jpeg")
.downloadToFile("/home/william/blob.jpeg");
以上代码使用我注册的应用程序创建一个 BlobClient
下载我的 blob 文件。这有效的事实表明我的应用程序确实具有访问我的存储容器所需的角色。
我想创建第二个演示来做同样的事情,但我想明确获取访问令牌并使用它来授权对 blob api 的普通 http 请求。到目前为止,这是我制作的:
private static final String TENANT_ID = "4b106bc5-7518-4f86-a259-f5726d124732";
private static final String CLIENT_ID = "11518eab-7b5a-493c-8d12-27731fe51341";
private static final String AUTHORITY = "https://login.microsoftonline.com/" + TENANT_ID;
private static final Set<String> SCOPE = Collections.singleton("api://" + CLIENT_ID + "/.default");
InputStream pkcs12Cert = new FileInputStream("/home/william/cert/new/azure.p12");
String certPwd = "password123";
IClientCredential credential = ClientCredentialFactory.createFromCertificate(pkcs12Cert, certPwd);
ConfidentialClientApplication cca = ConfidentialClientApplication
.builder(CLIENT_ID, credential).authority(AUTHORITY).build();
ClientCredentialParameters parameters = ClientCredentialParameters.builder(SCOPE).build();
IAuthenticationResult result = cca.acquireToken(parameters).join();
String token = result.accessToken();
URI uri = new URI("https://wemsa.blob.core.windows.net/wemco/spiral.jpeg");
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.header("Authorization", "Bearer " + token)
.header("Date", formatNow())
.header("x-ms-version", "2020-06-12")
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode()); // 401 !!!
这使用与第一个演示相同的注册应用。调试告诉我它正在成功获取访问令牌。但是,当我尝试使用它们时,我总是会收到 401 响应。我曾希望第一个演示运行正常,第二个演示也能自动运行 - 但它没有。
- 我想做的事情是否可行?
- 我第二个demo的代码有问题吗?
- 在演示 2 运行之前,我是否需要在 Azure 中进行更多设置?一些 Azure 文档提到创建一个应用程序角色,我试过了,但我不知道如何处理它。
有什么建议吗?
附加信息:这是我在 Azure 中所做的(接受所有默认值):
- 创建存储帐户wemsa
- 在 wemsa 中创建容器 wemco
- 上传(小)文件 'spiral.jpeg' 到容器 wemco
- 创建应用注册wemapp
- 将证书 'azure.crt' 上传到 wemapp
然后我回到容器wemco并且:
- 将角色 'Storage Blob Data Contributor' 授予 wemapp
这足以使演示 1 工作。
通过将范围(即请求的资源)更改为 azure 存储来修复:
private static final Set<String> SCOPE =
Collections.singleton("https://storage.azure.com//.default");
进行此更改后,我可以使用原始帖子中的演示 2 代码下载我的 blob 文件。