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

ID Token should be updated when Access Token is refreshed/acquired silently #2141

Merged
merged 6 commits into from
May 3, 2024

Conversation

spetrescu84
Copy link
Contributor

Proposed changes

The Auth Tokens present in the UserAccountResult and specifically the ID Token alongside the MSALAccount get updated when a refresh token operation happens

Type of change

  • Feature work
  • Bug fix
  • Documentation
  • Engineering change
  • Test
  • Logging/Telemetry

Risk

  • High – Errors could cause MAJOR regression of many scenarios. (Example: new large features or high level infrastructure changes)
  • Medium – Errors could cause regression of 1 or more scenarios. (Example: somewhat complex bug fixes, small new features)
  • Small – No issues are expected. (Example: Very small bug fixes, string changes, or configuration settings changes)

Additional information

To test this, the test case Verify split issuer needs to be run. The UserAccountResult returned when the getAccount is called, needs to have the ID Token updated when refreshToken is called and the MSALAccount should have the Account Claims updated

@spetrescu84 spetrescu84 added the native-auth Code related to native authentication label May 1, 2024
@spetrescu84 spetrescu84 self-assigned this May 1, 2024
@spetrescu84 spetrescu84 requested a review from a team as a code owner May 1, 2024 10:16
@@ -83,7 +83,9 @@ final class MSALNativeAuthCredentialsController: MSALNativeAuthTokenController,
return nil

Choose a reason for hiding this comment

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

This pull request does not update CHANGELOG.md.

Please consider if this change would be noticeable to a partner or user and either update CHANGELOG.md or resolve this conversation.

@@ -182,12 +189,40 @@ final class MSALNativeAuthCredentialsController: MSALNativeAuthTokenController,
context: context,
format: "Refresh Token completed successfully")
// TODO: Handle tokenResult.refreshToken as? MSIDRefreshToken in a safer way
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that we are changing this part, can you handle this TODO comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to factory, so removed

Copy link
Contributor

@diegojerezba diegojerezba left a comment

Choose a reason for hiding this comment

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

Left a small comment but LGTM, there isn't a reference cycle between MSALNativeAuthUserAccountResult and CredentialsController (I was a bit wary of the UserAccountResult passing itself to the CredentialsController, but it seems the object is being correctly deallocated).

let configuration: MSALNativeAuthConfiguration
private let cacheAccessor: MSALNativeAuthCacheInterface

/// Get the ID token for the account.
/// Get the latest ID token for the account.
@objc public var idToken: String? {
authTokens.rawIdToken
Copy link
Contributor

@diegojerezba diegojerezba May 2, 2024

Choose a reason for hiding this comment

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

@spetrescu84 did you consider retrieving the id token from the cache here? Maybe that would be a cleaner way, as you wouldn't have to make the account property mutable and would avoid most of the new changes.

I'm not sure if the performance would be affected too much, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we retrieve from cache we would need an account and it could be the access token is expired so we would need to get a new one so this property would need to have a completion so I don't think it would work.
Currently the account that is retrieved is the first one from cache, but if neither exist, the MSALNativeAuthUserAccountResult will not be created.
In the following scenario:
-App retrieves from cache the MSALAccount and a MSALNativeAuthUserAccountResult gets created
-Another app deletes the cache and the MSALAccount gets deleted from cache
-We try to get it again from cache and it fails because it's no longer there
I am simplifying it because the MSALAccount actually gets created out of a IDToken but I'd say the way we do it now works best as we have it in memory and don't have to deal with the change to cache/expiration.
I don't think there's a way around making it mutable here

do {
let claims = try MSIDIdTokenClaims.init(rawIdToken: tokenResult.rawIdToken)
jsonDictionary = claims.jsonDictionary()
if jsonDictionary == nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do claims needs to be always not nil?

Copy link
Contributor Author

@spetrescu84 spetrescu84 May 3, 2024

Choose a reason for hiding this comment

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

Claims can be nil, MSAL Objective C logs as a warning if a MSIDTokenResult cannot be converted to a MSALResult, regardless if claims cannot be created. Account is always created.
MSID_LOG_WITH_CTX_PII(MSIDLogLevelWarning, nil, @"MSALErrorConverter could not convert MSIDTokenResult to MSALResult %@", MSID_PII_LOG_MASKABLE(resultError))
Changed the level to a warning one.

@@ -169,11 +174,13 @@ final class MSALNativeAuthCredentialsController: MSALNativeAuthTokenController,
}
}

// swiftlint:disable:next function_body_length
Copy link
Contributor

@nilo-ms nilo-ms May 2, 2024

Choose a reason for hiding this comment

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

can you move the claims extraction/account creation in another private method? So, we don't need to add an exception here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No longer needed as it was all moved to the MSALNativeAuthResultBuildable

context: context,
format: "Claims for account could not be created - \(error)" )
}
guard let account = MSALAccount.init(msidAccount: tokenResult.account,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we reuse the code from the MSALNativeAuthResultFactory class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reused, created 2 new function to create the account and create the authTokens in the factory
func makeAccount(tokenResult: MSIDTokenResult, context: MSIDRequestContext) -> MSALAccount?
func makeAuthTokens(tokenResult: MSIDTokenResult, context: MSIDRequestContext) -> MSALNativeAuthTokens?

responseValidatorMock.tokenValidatedResponse = .success(tokenResponse)
cacheAccessorMock.mockUserAccounts = [account]
cacheAccessorMock.mockUserAccounts = [newAccount!]
Copy link
Contributor

Choose a reason for hiding this comment

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

can we avoid the force unwrap here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd say we are ok with force unwraps in unit tests. No point to add guards here.

Copy link
Contributor

Choose a reason for hiding this comment

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

The only point is that if newAccount is nil, we crash, and all the next tests are not executed. While if we gracefully unwrap it only this test will fail

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have that in many tests such as MSALNativeAuthUrlRequestSerializerTests or MSALNativeAuthResponseErrorHandlerTests. The idea is for them to be succinct. I can add it but we should have all tests behave the same because if the tests in any other classes fail, it will stop execution also.

@@ -121,13 +121,14 @@ final class MSALNativeAuthCredentialsControllerTests: MSALNativeAuthTestCase {

let expectedContext = MSALNativeAuthRequestContext(correlationId: defaultUUID)
Copy link
Contributor

Choose a reason for hiding this comment

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

can you also test the case when the account claims can't be parsed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added, but not here, but rather in MSALNativeAuthResultFactoryTests as that's where it should be. Also changed how the code works because the MSALAccount always gets created no matter what as it's not an optional (we had it wrong because of Objective C/Swift interoperability).
Changed the names of the tests on this class to highlight the userAccountResult doesn't get created rather than the account

@spetrescu84 spetrescu84 merged commit 28bcbef into dev May 3, 2024
6 checks passed
antonioalwan added a commit that referenced this pull request May 9, 2024
* dev:
  Update automation.yml for Azure Pipelines
  Update automation.yml for Azure Pipelines
  Update automation.yml for Azure Pipelines
  ID Token should be updated when Access Token is refreshed/acquired silently (#2141)
  So support ssh-cert flow through broker (Update submodule only) (#2134)

# Conflicts:
#	MSAL/IdentityCore
antrix1989 added a commit that referenced this pull request May 17, 2024
* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Delete spm-framework.yml

* Update from dev

* remove test

* Reintroduce Minimum OS Version Requirements to Readme

Reintroducing minimum version indicators that were [mistakenly?] removed in #2080

* So support ssh-cert flow through broker (Update submodule only) (#2134)

* cc update

* Update submodule

* Update submodule

* ID Token should be updated when Access Token is refreshed/acquired silently (#2141)

* Changed refresh token to update account and tokens on UserAccountResult

* Unit tests

* Swiftlint

* Updated code comment

* PR Comments

* Update automation.yml for Azure Pipelines

* Update automation.yml for Azure Pipelines

* Update automation.yml for Azure Pipelines

* This PR removes the ADAL keyvault and client secret (#2150)

* Update submodule

* Update yml file

* Revert conf file from testings

* Update msal submodule (#2160)

* Update core.

* Bump version.

* modified:   CHANGELOG.md

* modified:   IdentityCore

---------

Co-authored-by: Ameya Patil <ameyapat@buffalo.edu>
Co-authored-by: Ameya <>
Co-authored-by: Antonio Alwan <antonioalwan@microsoft.com>
Co-authored-by: Hieu Nguyen <hiengu@microsoft.com>
Co-authored-by: Ameya Patil <amepatil@microsoft.com>
Co-authored-by: Hieu Nguyen <65981263+hieunguyenmsft@users.noreply.github.com>
Co-authored-by: Brian Melton-Grace <iambmelton@gmail.com>
Co-authored-by: Kai <kaisong1990@gmail.com>
Co-authored-by: Silviu Petrescu <111577419+spetrescu84@users.noreply.github.com>
Co-authored-by: Swasti Gupta <swastinitb@gmail.com>
antrix1989 added a commit that referenced this pull request May 21, 2024
* Update core.

* Bump version.

* modified:   CHANGELOG.md

* modified:   IdentityCore

* Merge release 1.3.3 to main (#2165)

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Update msal-release-ado-trigger.yml for Azure Pipelines

* Delete spm-framework.yml

* Update from dev

* remove test

* Reintroduce Minimum OS Version Requirements to Readme

Reintroducing minimum version indicators that were [mistakenly?] removed in #2080

* So support ssh-cert flow through broker (Update submodule only) (#2134)

* cc update

* Update submodule

* Update submodule

* ID Token should be updated when Access Token is refreshed/acquired silently (#2141)

* Changed refresh token to update account and tokens on UserAccountResult

* Unit tests

* Swiftlint

* Updated code comment

* PR Comments

* Update automation.yml for Azure Pipelines

* Update automation.yml for Azure Pipelines

* Update automation.yml for Azure Pipelines

* This PR removes the ADAL keyvault and client secret (#2150)

* Update submodule

* Update yml file

* Revert conf file from testings

* Update msal submodule (#2160)

* Update core.

* Bump version.

* modified:   CHANGELOG.md

* modified:   IdentityCore

---------

Co-authored-by: Ameya Patil <ameyapat@buffalo.edu>
Co-authored-by: Ameya <>
Co-authored-by: Antonio Alwan <antonioalwan@microsoft.com>
Co-authored-by: Hieu Nguyen <hiengu@microsoft.com>
Co-authored-by: Ameya Patil <amepatil@microsoft.com>
Co-authored-by: Hieu Nguyen <65981263+hieunguyenmsft@users.noreply.github.com>
Co-authored-by: Brian Melton-Grace <iambmelton@gmail.com>
Co-authored-by: Kai <kaisong1990@gmail.com>
Co-authored-by: Silviu Petrescu <111577419+spetrescu84@users.noreply.github.com>
Co-authored-by: Swasti Gupta <swastinitb@gmail.com>

* modified:   MSAL/IdentityCore

* Updating MSAL framework checksum & url for 1.3.3 [skip ci]

---------

Co-authored-by: Ameya Patil <ameyapat@buffalo.edu>
Co-authored-by: Antonio Alwan <antonioalwan@microsoft.com>
Co-authored-by: Hieu Nguyen <hiengu@microsoft.com>
Co-authored-by: Ameya Patil <amepatil@microsoft.com>
Co-authored-by: Hieu Nguyen <65981263+hieunguyenmsft@users.noreply.github.com>
Co-authored-by: Brian Melton-Grace <iambmelton@gmail.com>
Co-authored-by: Kai <kaisong1990@gmail.com>
Co-authored-by: Silviu Petrescu <111577419+spetrescu84@users.noreply.github.com>
Co-authored-by: Swasti Gupta <swastinitb@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
native-auth Code related to native authentication
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants