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

[Bug fix] Use hub app's FRT to get nested app's AT #2379

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,15 @@
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;
import com.microsoft.identity.common.java.providers.microsoft.MicrosoftAuthorizationRequest;
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;
Expand Down Expand Up @@ -460,6 +462,70 @@ protected TokenResult performTokenRequest(@SuppressWarnings(WarningType.rawtype_
return tokenResult;
}

/**
* Renewing AT of nested app.
*/
protected synchronized void renewAccessTokenForNestedApp(@NonNull final SilentTokenCommandParameters parameters,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renewAccessTokenForNestedApp

Why in BaseController? would non broker controller need this?
This method by itself has no check around NAA or FOCI, so can be called erroneously.

I think Foci RT request logic can be directly inside a BrokerLocalController private method. Then you can call renewAccessToken()

Copy link
Contributor Author

@somalaya somalaya Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This is not required in any other cases. Moved it to BrokerLocalController.

@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();
somalaya marked this conversation as resolved.
Show resolved Hide resolved
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<ICacheRecord> 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()) {
somalaya marked this conversation as resolved.
Show resolved Hide resolved
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,
Expand Down
Loading