Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
blacelle opened this issue Apr 28, 2021 · 2 comments
Open

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

blacelle opened this issue Apr 28, 2021 · 2 comments

Comments

@blacelle
Copy link

blacelle commented Apr 28, 2021

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

@blacelle
Copy link
Author

@blacelle
Copy link
Author

I confirm something like:

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

unlock such a situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant