Skip to content

AzureCliToken isMRRT flag is not updated correctly on token clone #704

@blacelle

Description

@blacelle

In my case, the CLI get a refreshToken for "https://management.core.windows.net/" with isMRRT=true. I later request a token for "https://graph.microsoft.com": the management token is used to generate a new token for "https://graph.microsoft.com".

This second token has no refreshToken (for any reason): fine. However, the second token registered by AzureCliSubscription keep s isMRRT=true due to its .clone implementation:

https://github.com/Azure/autorest-clientruntime-for-java/blob/master/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/AzureCliSubscription.java#L136

  AuthenticationResult authenticationResult = acquireAccessTokenFromRefreshToken(resource, token.refreshToken());
                       if (authenticationResult == null) {
                           return null;
                       }
                       try {
                           AzureCliToken newToken = token.clone().withResource(resource).withAuthenticationResult(authenticationResult);
                           userTokens.put(resource, newToken);
                           return newToken.accessToken();
                       } catch (CloneNotSupportedException e) {
                           throw new RuntimeException(e);
                       }

https://github.com/Azure/autorest-clientruntime-for-java/blob/master/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/AzureCliToken.java#L84

  AzureCliToken withAuthenticationResult(AuthenticationResult result) {
       this.accessToken = result.getAccessToken();
       this.refreshToken = result.getRefreshToken();
       this.expiresIn = result.getExpiresAfter();
       this.expiresOnDate = result.getExpiresOnDate();
       return this;
   }

It then leads to an obscure:

Caused by: java.lang.RuntimeException: java.io.IOException: The value must not be null or empty string
	at rx.exceptions.Exceptions.propagate(Exceptions.java:57) ~[rxjava-1.3.8.jar:1.3.8]
	at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:463) ~[rxjava-1.3.8.jar:1.3.8]
	at rx.observables.BlockingObservable.single(BlockingObservable.java:340) ~[rxjava-1.3.8.jar:1.3.8]
	at com.microsoft.azure.management.graphrbac.implementation.ActiveDirectoryApplicationsImpl.getByName(ActiveDirectoryApplicationsImpl.java:116) ~[azure-mgmt-graph-rbac-1.38.1.jar:1.38.1]
	at com.microsoft.azure.management.graphrbac.implementation.ActiveDirectoryApplicationsImpl.getByName(ActiveDirectoryApplicationsImpl.java:30) ~[azure-mgmt-graph-rbac-1.38.1.jar:1.38.1]
[XXX]
	... 5 common frames omitted
Caused by: java.io.IOException: The value must not be null or empty string
	at com.microsoft.azure.credentials.UserTokenCredentials.acquireAccessTokenFromRefreshToken(UserTokenCredentials.java:129) ~[azure-client-authentication-1.6.13.jar:na]
	at com.microsoft.azure.credentials.AzureCliSubscription$1.getToken(AzureCliSubscription.java:124) ~[azure-client-authentication-1.6.13.jar:na]
	at com.microsoft.azure.credentials.AzureCliCredentials.getToken(AzureCliCredentials.java:123) ~[azure-client-authentication-1.6.13.jar:na]
	at com.microsoft.azure.credentials.AzureTokenCredentials.getToken(AzureTokenCredentials.java:74) ~[azure-client-runtime-1.7.12.jar:na]
	at com.microsoft.azure.credentials.AzureTokenCredentialsInterceptor.intercept(AzureTokenCredentialsInterceptor.java:36) ~[azure-client-runtime-1.7.12.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.9.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.9.jar:na]
	at com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor.intercept(ResourceManagerThrottlingInterceptor.java:56) ~[azure-mgmt-resources-1.38.1.jar:1.38.1]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.9.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.9.jar:na]
	at com.microsoft.azure.management.resources.fluentcore.utils.ProviderRegistrationInterceptor.intercept(ProviderRegistrationInterceptor.java:40) ~[azure-mgmt-resources-1.38.1.jar:1.38.1]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.9.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.9.jar:na]
	at com.microsoft.rest.interceptors.BaseUrlHandler.intercept(BaseUrlHandler.java:43) ~[client-runtime-1.6.13.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.9.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.9.jar:na]
	at com.microsoft.rest.interceptors.RequestIdHeaderInterceptor.intercept(RequestIdHeaderInterceptor.java:29) ~[client-runtime-1.6.13.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.9.jar:na]
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.9.jar:na]
	at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229) ~[okhttp-3.14.9.jar:na]
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:172) ~[okhttp-3.14.9.jar:na]
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) ~[okhttp-3.14.9.jar:na]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_172]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_172]
	at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_172]
Caused by: java.lang.IllegalArgumentException: The value must not be null or empty string
	at com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:92) ~[oauth2-oidc-sdk-7.1.1.jar:7.1.1]
	at com.nimbusds.oauth2.sdk.token.Token.<init>(Token.java:49) ~[oauth2-oidc-sdk-7.1.1.jar:7.1.1]
	at com.nimbusds.oauth2.sdk.token.RefreshToken.<init>(RefreshToken.java:76) ~[oauth2-oidc-sdk-7.1.1.jar:7.1.1]
	at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenByRefreshToken(AuthenticationContext.java:894) ~[adal4j-1.6.4.jar:1.6.4]
	at com.microsoft.azure.credentials.UserTokenCredentials.acquireAccessTokenFromRefreshToken(UserTokenCredentials.java:126) ~[azure-client-authentication-1.6.13.jar:na]
	... 24 common frames omitted

KO as we try to refresh based on a null refresh_token.

I have the issue with 1.6.13, but the code seems equivalent in 1.6.15 and 1.7.X

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions