-
Notifications
You must be signed in to change notification settings - Fork 142
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
Conversation
@@ -83,7 +83,9 @@ final class MSALNativeAuthCredentialsController: MSALNativeAuthTokenController, | |||
return nil |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
* 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
* 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>
* 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>
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
Risk
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