[BUG] Using DefaultAzureCredential, second request returns 403
See original GitHub issueDescribe the bug
I’m using DefaultAzureCredential to authenticate through Azure CLI (via az login
). With the azure-storage-blob SDK I can complete one GET operation, but any subsequent GETs return a 403.
Exception or Stack Trace
com.azure.storage.blob.models.BlobContainerItem@a1f72f5
Exception in thread "main" com.azure.storage.blob.models.BlobStorageException: Status code 403, "<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.
RequestId:d509520c-d01e-00a8-6cdb-09ef73000000
Time:2020-04-03T17:12:28.6748208Z</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:357)
at com.azure.core.http.rest.RestProxy.lambda$ensureExpectedStatus$3(RestProxy.java:400)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1592)
at reactor.core.publisher.MonoProcessor.onNext(MonoProcessor.java:317)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2148)
at reactor.core.publisher.MonoProcessor.onSubscribe(MonoProcessor.java:325)
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:48)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.Mono.subscribe(Mono.java:4087)
at reactor.core.publisher.MonoProcessor.add(MonoProcessor.java:457)
at reactor.core.publisher.MonoProcessor.subscribe(MonoProcessor.java:370)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
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:103)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1592)
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.terminateReceiver(FluxReceive.java:419)
at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:209)
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:367)
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:363)
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:412)
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:572)
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:90)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:316)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1470)
at io.netty.handler.ssl.SslHandler.decodeNonJdkCompatible(SslHandler.java:1231)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1268)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:493)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:271)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
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)
To Reproduce
az login
public class AzLogin {
public static void main(String[] args) {
final String endpoint = "https://mystorageaccount.blob.core.windows.net";
final String container = "mycontainer";
final String prefix = "customer";
DefaultAzureCredential creds = new DefaultAzureCredentialBuilder().build();
final BlobServiceClientBuilder clientBuilder = new BlobServiceClientBuilder();
clientBuilder.endpoint(endpoint);
clientBuilder.credential(creds);
BlobServiceClient client = clientBuilder.buildClient();
// This works
client.listBlobContainers().forEach(System.out::println);
BlobContainerClient blobContainerClient = client.getBlobContainerClient(container);
ListBlobsOptions blobOptions = new ListBlobsOptions().setPrefix(prefix);
// This and other requests return 403
blobContainerClient.listBlobs(blobOptions, Duration.ofSeconds(60)).forEach(BlobItem::getName);
}
}
Expected behavior I’d expect that once setup, all requests would be authenticated, not just the first. Setup (please complete the following information):
- OS: Mac OS 10.15.4
- IDE : IntelliJ
- Version of the Library used: Java azure-identity 1.1.0-beta.2
- Java version: AdoptJDK 1.8.0-212
Additional context Authenticating using a StorageSharedKeyCredential (storage account name, key) in BlobServiceClientBuilder works fine, so I don’t believe it’s a matter of blob permissions (also this account has no special permissions applied).
Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report
- Bug Description Added
- Repro Steps Added
- Setup information Added
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Ah, you’re right. I didn’t understand that it would need the Azure AD Authentication Method instead of the Access Key method as explained here https://docs.microsoft.com/en-us/azure/storage/common/storage-access-blobs-queues-portal
I gave my account Reader and Storage Blob Data Reader roles and after a few minutes I was able to list blobs in my storage account, having authenticated with
az login
previously. Sorry for the noise.@rothwerx, what permissions does the account/identity have in the Storage service?