From a85eb8dee9b347ff6708cadad0ab5ae10e50006a Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Fri, 12 Apr 2024 11:56:14 -0700 Subject: [PATCH 1/4] renew AT using FRT logic for nested app --- .../java/controllers/BaseController.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java index 86b7f42868..7557a769c7 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java +++ b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java @@ -58,6 +58,7 @@ import com.microsoft.identity.common.java.exception.ClientException; import com.microsoft.identity.common.java.exception.ErrorStrings; import com.microsoft.identity.common.java.exception.ServiceException; +import com.microsoft.identity.common.java.exception.UiRequiredException; import com.microsoft.identity.common.java.foci.FociQueryUtilities; import com.microsoft.identity.common.java.logging.DiagnosticContext; import com.microsoft.identity.common.java.logging.Logger; @@ -65,6 +66,7 @@ import com.microsoft.identity.common.java.providers.microsoft.MicrosoftTokenRequest; import com.microsoft.identity.common.java.providers.microsoft.microsoftsts.MicrosoftStsAuthorizationRequest; import com.microsoft.identity.common.java.providers.microsoft.microsoftsts.MicrosoftStsOAuth2Strategy; +import com.microsoft.identity.common.java.providers.microsoft.microsoftsts.MicrosoftStsTokenRequest; import com.microsoft.identity.common.java.providers.microsoft.microsoftsts.MicrosoftStsTokenResponse; import com.microsoft.identity.common.java.providers.oauth2.AuthorizationRequest; import com.microsoft.identity.common.java.providers.oauth2.AuthorizationResponse; @@ -460,6 +462,71 @@ protected TokenResult performTokenRequest(@SuppressWarnings(WarningType.rawtype_ return tokenResult; } + /** + * Renewing AT of nested app. + */ + protected synchronized void renewAccessTokenForNestedApp(@NonNull final SilentTokenCommandParameters parameters, + @NonNull final AcquireTokenResult acquireTokenSilentResult, + @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2TokenCache tokenCache, + @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2Strategy strategy, + @NonNull final ICacheRecord cacheRecord) + throws IOException, ClientException, ServiceException { + final String methodTag = TAG + ":renewAccessTokenForNestedApp"; + Logger.info( + methodTag, + "Renewing access token for nested app..." + ); + + RefreshTokenRecord refreshTokenRecord = cacheRecord.getRefreshToken(); + + logParameters(methodTag, parameters); + + // 1. First get RT of hub app using FRT. Only a hub app's RT can be used to renew AT of nested app + // Create a correlation_id for the request + final UUID correlationId = UUID.randomUUID(); + Logger.verbose(methodTag, + "Create the token request with correlationId [" + + correlationId + + "]"); + final MicrosoftStsTokenRequest tokenRequest = FociQueryUtilities.createTokenRequest(parameters.getClientId(), getDelimitedDefaultScopeString(), + refreshTokenRecord.getSecret(), parameters.getRedirectUri(), (MicrosoftStsOAuth2Strategy) strategy, correlationId, "2"); + final TokenResult tokenResult = strategy.requestToken(tokenRequest); + + if (tokenResult.getSuccess()) { + final MicrosoftStsTokenResponse tokenResponse = (MicrosoftStsTokenResponse) tokenResult.getTokenResponse(); + Logger.info( + methodTag, + "Token request was successful" + ); + List acquireTokenResultRecords = getAcquireTokenResultRecords(tokenResponse, (MicrosoftStsOAuth2Strategy) strategy, + (MicrosoftStsAuthorizationRequest) getAuthorizationRequest(strategy, parameters)); + // 2. + // + // qUsing above cache record with hub app's FRT, we will renew AT for nested app. + if (!acquireTokenResultRecords.isEmpty()) { + renewAccessToken( + parameters, + acquireTokenSilentResult, + tokenCache, + strategy, + acquireTokenResultRecords.get(0) + ); + } + } else { + if (tokenResult.getErrorResponse() != null) { + final String errorCode = tokenResult.getErrorResponse().getError(); + Logger.info(methodTag, "Fetching Hub app RT with FRT failed with Error: " + errorCode + " SubError: " + tokenResult.getErrorResponse().getSubError()); + if (SERVICE_NOT_AVAILABLE.equals(errorCode)) { + throw new ServiceException(SERVICE_NOT_AVAILABLE, "AAD is not available.", tokenResult.getErrorResponse().getStatusCode(), null); + } else { + throw new ClientException(ErrorStrings.NO_TOKENS_FOUND, "No valid RT found for hub app"); + } + } else { + Logger.warn(methodTag, "Invalid state, No token success or error response on the token result"); + } + } + } + protected void renewAccessToken(@NonNull final SilentTokenCommandParameters parameters, @NonNull final AcquireTokenResult acquireTokenSilentResult, @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2TokenCache tokenCache, From f7cef53c512cea26cf10ea674aa25e630daaa9bf Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Fri, 12 Apr 2024 12:12:35 -0700 Subject: [PATCH 2/4] changeLog updated --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog.txt b/changelog.txt index c22cc43fed..047489a964 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,6 +6,8 @@ V.Next - [PATCH] Return status code in errorResponse when server response is not in expected Json format. (#2321) - [PATCH] Reduce the amount of setAccountVisibility() call. (#2355) - [MINOR] Added telemetry for cross cloud and MSA passthrough requests (#2367) +- [MINOR] [Bug fix] Use hub app's FRT to get nested app's AT (#2379) + V.17.2.0 --------- From 17bf7c4d90fa5016575d198536bcf478768319fa Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur <69237821+somalaya@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:05:46 -0700 Subject: [PATCH 3/4] removed newline --- .../identity/common/java/controllers/BaseController.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java index 7557a769c7..cc331c74cb 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java +++ b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java @@ -500,9 +500,8 @@ protected synchronized void renewAccessTokenForNestedApp(@NonNull final SilentTo ); List acquireTokenResultRecords = getAcquireTokenResultRecords(tokenResponse, (MicrosoftStsOAuth2Strategy) strategy, (MicrosoftStsAuthorizationRequest) getAuthorizationRequest(strategy, parameters)); - // 2. - // - // qUsing above cache record with hub app's FRT, we will renew AT for nested app. + + // 2. Using above cache record with hub app's FRT, we will renew AT for nested app. if (!acquireTokenResultRecords.isEmpty()) { renewAccessToken( parameters, From 033c278601da4b5a3f6b24f221c57f62874550cb Mon Sep 17 00:00:00 2001 From: Sowmya Malayanur Date: Fri, 12 Apr 2024 15:55:23 -0700 Subject: [PATCH 4/4] Moved entire logic to BrokerLocalController --- .../java/controllers/BaseController.java | 66 +------------------ 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java index cc331c74cb..ce68834385 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java +++ b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java @@ -462,70 +462,6 @@ protected TokenResult performTokenRequest(@SuppressWarnings(WarningType.rawtype_ return tokenResult; } - /** - * Renewing AT of nested app. - */ - protected synchronized void renewAccessTokenForNestedApp(@NonNull final SilentTokenCommandParameters parameters, - @NonNull final AcquireTokenResult acquireTokenSilentResult, - @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2TokenCache tokenCache, - @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2Strategy strategy, - @NonNull final ICacheRecord cacheRecord) - throws IOException, ClientException, ServiceException { - final String methodTag = TAG + ":renewAccessTokenForNestedApp"; - Logger.info( - methodTag, - "Renewing access token for nested app..." - ); - - RefreshTokenRecord refreshTokenRecord = cacheRecord.getRefreshToken(); - - logParameters(methodTag, parameters); - - // 1. First get RT of hub app using FRT. Only a hub app's RT can be used to renew AT of nested app - // Create a correlation_id for the request - final UUID correlationId = UUID.randomUUID(); - Logger.verbose(methodTag, - "Create the token request with correlationId [" - + correlationId - + "]"); - final MicrosoftStsTokenRequest tokenRequest = FociQueryUtilities.createTokenRequest(parameters.getClientId(), getDelimitedDefaultScopeString(), - refreshTokenRecord.getSecret(), parameters.getRedirectUri(), (MicrosoftStsOAuth2Strategy) strategy, correlationId, "2"); - final TokenResult tokenResult = strategy.requestToken(tokenRequest); - - if (tokenResult.getSuccess()) { - final MicrosoftStsTokenResponse tokenResponse = (MicrosoftStsTokenResponse) tokenResult.getTokenResponse(); - Logger.info( - methodTag, - "Token request was successful" - ); - List acquireTokenResultRecords = getAcquireTokenResultRecords(tokenResponse, (MicrosoftStsOAuth2Strategy) strategy, - (MicrosoftStsAuthorizationRequest) getAuthorizationRequest(strategy, parameters)); - - // 2. Using above cache record with hub app's FRT, we will renew AT for nested app. - if (!acquireTokenResultRecords.isEmpty()) { - renewAccessToken( - parameters, - acquireTokenSilentResult, - tokenCache, - strategy, - acquireTokenResultRecords.get(0) - ); - } - } else { - if (tokenResult.getErrorResponse() != null) { - final String errorCode = tokenResult.getErrorResponse().getError(); - Logger.info(methodTag, "Fetching Hub app RT with FRT failed with Error: " + errorCode + " SubError: " + tokenResult.getErrorResponse().getSubError()); - if (SERVICE_NOT_AVAILABLE.equals(errorCode)) { - throw new ServiceException(SERVICE_NOT_AVAILABLE, "AAD is not available.", tokenResult.getErrorResponse().getStatusCode(), null); - } else { - throw new ClientException(ErrorStrings.NO_TOKENS_FOUND, "No valid RT found for hub app"); - } - } else { - Logger.warn(methodTag, "Invalid state, No token success or error response on the token result"); - } - } - } - protected void renewAccessToken(@NonNull final SilentTokenCommandParameters parameters, @NonNull final AcquireTokenResult acquireTokenSilentResult, @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2TokenCache tokenCache, @@ -736,7 +672,7 @@ public TokenResult renewAccessToken(@NonNull final SilentTokenCommandParameters return tokenResult; } - private List getAcquireTokenResultRecords(@NonNull final MicrosoftStsTokenResponse microsoftStsTokenResponse, + protected List getAcquireTokenResultRecords(@NonNull final MicrosoftStsTokenResponse microsoftStsTokenResponse, @NonNull final MicrosoftStsOAuth2Strategy oAuth2Strategy, @NonNull final MicrosoftStsAuthorizationRequest authorizationRequest) { final MicrosoftStsAccountCredentialAdapter credentialAdapter = new MicrosoftStsAccountCredentialAdapter();