使用Azure SDK和Java下载带有用户委派SAS的Blob

使用Azure SDK和Java下载带有用户委派SAS的Blob,java,azure,azure-active-directory,azure-sdk,Java,Azure,Azure Active Directory,Azure Sdk,我正在尝试使用一个使用用户委派SAS的Java程序下载blob内容 下面是我准备的代码片段- String accountName = mapString.get("accountName"); String blobEndpoint = mapString.get("endpoint"); BlobServiceClient storageClient = new BlobServiceClientB

我正在尝试使用一个使用用户委派SAS的Java程序下载blob内容

下面是我准备的代码片段-


        String accountName = mapString.get("accountName");

        String blobEndpoint = mapString.get("endpoint");

        BlobServiceClient storageClient = new BlobServiceClientBuilder().endpoint(blobEndpoint)
                .credential(new DefaultAzureCredentialBuilder().build()).buildClient();

        UserDelegationKey key = storageClient.getUserDelegationKey(OffsetDateTime.now(),
                OffsetDateTime.now().plusDays(5));

        BlobServiceSasSignatureValues signatureValues = new BlobServiceSasSignatureValues(
                OffsetDateTime.now().plusDays(5), BlobContainerSasPermission.parse("rwdl"));

        String userDelegationSas = new BlobSasImplUtil(signatureValues,"demo").generateUserDelegationSas(key,
                accountName);

        System.out.println("user sas " + userDelegationSas);

        BlobContainerClient containerClient = new BlobContainerClientBuilder()
                .containerName("demo")
                .endpoint("https://xyz.blob.core.windows.net/" + "?" + userDelegationSas)
                .credential(new DefaultAzureCredentialBuilder().build()).buildClient();
        

        containerClient.listBlobs().forEach(blobItem -> {
            System.out.println("Item Name" + blobItem.getName());
            BlobClient blobClient = containerClient.getBlobClient(blobItem.getName());
            blobClient.downloadToFile(
                    fileDir
                            + blobItem.getName().replace("/", "-"));
我正在使用Eclipse,并使用azure CLI登录到我的azure帐户,并且我有
我尝试访问的存储帐户的存储Blob数据参与者角色

似乎用户委派sas正在创建中,但在尝试获取容器客户端时遇到了以下问题

Exception in thread "main" com.azure.storage.blob.models.BlobStorageException: Status code 404, "<?xml version="1.0" encoding="utf-8"?><Error><Code>ContainerNotFound</Code><Message>The specified container does not exist.
RequestId:4b2ef531-f01e-001d-3b73-937eba000000
Time:2020-09-25T19:36:11.3933989Z</Message></Error>"
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.azure.core.http.rest.RestProxy.instantiateUnexpectedException(RestProxy.java:320)
    at com.azure.core.http.rest.RestProxy.lambda$ensureExpectedStatus$3(RestProxy.java:361)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1755)
    at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:320)
    at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onNext(MonoCacheTime.java:337)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2317)
    at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onSubscribe(MonoCacheTime.java:276)
    at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:191)
    at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoCacheTime.subscribeOrReturn(MonoCacheTime.java:132)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)
    at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:123)
    at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:112)
    at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:213)
    at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:123)
    at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:178)
    at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:96)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1755)
    at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121)
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252)
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)
    at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:366)
    at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:367)
    at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:423)
    at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:607)
    at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1518)
    at io.netty.handler.ssl.SslHandler.decodeNonJdkCompatible(SslHandler.java:1279)
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1316)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

期待您的回复。谢谢。

已修复。要获取BlobContainerClient,还需要端点中的容器名称

BlobContainerClient containerClient = new BlobContainerClientBuilder()
                .endpoint("https://xyz.blob.core.windows.net/demo/" + "?" + userDelegationSas)
                .credential(new DefaultAzureCredentialBuilder().build()).buildClient();