-
Notifications
You must be signed in to change notification settings - Fork 50
Add OnboardingBlockingErrorParser bridging clitelem/error_codes into the onboarding blob, Fixes AB#3462876 #3122
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
Open
wzhipan
wants to merge
14
commits into
dev
Choose a base branch
from
zhipan/onboarding-telemetry-clitelem-v2
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+402
−0
Open
Changes from 12 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
3a8cec8
Add OnboardingBlockingErrorParser bridging x-ms-clitelem to onboardin…
wzhipan a01c5aa
OnboardingBlockingErrorParser: filter non-onboarding AADSTS error codes
wzhipan 02286fa
Add multi-value overload for OAuth error_codes parameter (Path B)
wzhipan d5fa191
Changelog: onboarding blocking-error parser
wzhipan fa2c034
Address review comments on PR #3122
wzhipan 0e48d33
Merge remote-tracking branch 'origin/dev' into zhipan/onboarding-tele…
wzhipan 9800042
Merge remote-tracking branch 'origin/dev' into zhipan/onboarding-tele…
wzhipan db6eeb3
Merge branch 'dev' into zhipan/onboarding-telemetry-clitelem-v2
wzhipan 7c11468
Merge branch 'dev' into zhipan/onboarding-telemetry-clitelem-v2
wzhipan 8ffe100
Re-trigger CI (previous run had infra-only failures: flaky coroutine …
wzhipan 6c77bf3
Merge branch 'dev' into zhipan/onboarding-telemetry-clitelem-v2
wzhipan 8fa1740
Merge branch 'dev' into zhipan/onboarding-telemetry-clitelem-v2
wzhipan 597df94
Move OnboardingBlockingErrorParser changelog entry from Version 24.3.…
wzhipan ac68a61
Merge branch 'dev' into zhipan/onboarding-telemetry-clitelem-v2
wzhipan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
158 changes: 158 additions & 0 deletions
158
...4j/src/main/com/microsoft/identity/common/java/telemetry/OnboardingBlockingErrorParser.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // All rights reserved. | ||
| // | ||
| // This code is licensed under the MIT License. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files(the "Software"), to deal | ||
| // in the Software without restriction, including without limitation the rights | ||
| // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | ||
| // copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions : | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| // THE SOFTWARE. | ||
| package com.microsoft.identity.common.java.telemetry | ||
|
|
||
| import com.microsoft.identity.common.java.providers.microsoft.MicrosoftTokenResponse | ||
|
|
||
| /** | ||
| * Bridges eSTS-emitted error codes (carried via the `x-ms-clitelem` header and parsed | ||
| * into [MicrosoftTokenResponse] by [com.microsoft.identity.common.java.providers.microsoft.microsoftsts.AbstractMicrosoftStsTokenResponseHandler]) | ||
| * into the onboarding telemetry blob's `last_blocking_error` / `blocking_errors` fields | ||
| * (see [OnboardingTelemetryConstants.LAST_BLOCKING_ERROR] / [OnboardingTelemetryConstants.BLOCKING_ERRORS]). | ||
| * | ||
| * Callers (OneAuth navigation fragment, broker error handler, etc.) invoke | ||
| * [extractBlockingError] on the [MicrosoftTokenResponse] of a failed token request | ||
| * to obtain a string suitable for | ||
| * [com.microsoft.identity.common.internal.telemetry.OnboardingTelemetryRecorder.addBlockingError]. | ||
| * | ||
|
wzhipan marked this conversation as resolved.
|
||
| * Returns null when the response carries no error or the error is not blocking. | ||
| * | ||
| * Per design spec (Mobile Onboarding Telemetry §10), the `x-ms-clitelem` header | ||
| * supplies both an `errorCode` (position 2) and a `subErrorCode` (position 3). | ||
| * This parser prefers the sub-error code when present (it is the most specific | ||
| * attribution signal) and falls back to the server error code; both are surfaced | ||
| * to the onboarding blob via `addBlockingError`. | ||
| */ | ||
| object OnboardingBlockingErrorParser { | ||
|
|
||
| /** | ||
| * AADSTS error codes that look like blocking errors syntactically (5-digit | ||
| * server error codes from eSTS) but are NOT onboarding-remediation signals. | ||
| * These flow through the parser the same as any other server error, so we | ||
| * filter them here at the policy boundary so callers don't have to. | ||
| * | ||
| * - 50058 UserInformationNotProvided (no SSO session — user just needs to sign in) | ||
| * - 50097 DeviceAuthenticationRequired (in-flow device auth challenge; if WPJ runs we | ||
| * already record DeviceRegistrationStarted as a step) | ||
| * - 50126 InvalidUserNameOrPassword (wrong credentials — user error) | ||
| */ | ||
| private val NON_ONBOARDING_AADSTS_CODES = setOf("50058", "50097", "50126") | ||
|
|
||
| /** | ||
| * Returns true if the candidate error code should be excluded from the | ||
| * onboarding blob's `blocking_errors[]`. See [NON_ONBOARDING_AADSTS_CODES]. | ||
| */ | ||
| private fun isExcluded(candidate: String): Boolean = candidate in NON_ONBOARDING_AADSTS_CODES | ||
|
|
||
| /** | ||
| * Extract a blocking-error attribution string from a [MicrosoftTokenResponse]. | ||
| * | ||
| * Returns the most specific available identifier: | ||
| * 1. `serverSubErrorCode` (e.g. `interaction_required`) if present and non-zero, else | ||
| * 2. `serverErrorCode` (e.g. `65001`) if present and non-zero, else | ||
| * 3. `null` (no blocking error to record). | ||
| * | ||
| * Position-2 of the `x-ms-clitelem` header is `0` when there is no error — those | ||
| * cases are filtered out so callers don't pollute the blob with `"0"`. | ||
| * | ||
| * Codes in [NON_ONBOARDING_AADSTS_CODES] are also filtered out as they are not | ||
| * onboarding-remediation signals. | ||
| * | ||
| * @return blocking error identifier suitable for `addBlockingError(...)`, or null | ||
| */ | ||
| @JvmStatic | ||
| fun extractBlockingError(tokenResponse: MicrosoftTokenResponse?): String? { | ||
| if (tokenResponse == null) return null | ||
|
|
||
| val subError = tokenResponse.cliTelemSubErrorCode | ||
| if (!subError.isNullOrBlank() && subError != "0" && !isExcluded(subError)) { | ||
| return subError | ||
| } | ||
|
|
||
| val error = tokenResponse.cliTelemErrorCode | ||
| if (!error.isNullOrBlank() && error != "0" && !isExcluded(error)) { | ||
| return error | ||
| } | ||
|
|
||
| return null | ||
| } | ||
|
|
||
| /** | ||
| * Convenience overload that parses a raw `x-ms-clitelem` header string directly. | ||
| * Useful when the caller does not have a [MicrosoftTokenResponse] in hand | ||
| * (e.g. parsing a redirect response in a WebView client). | ||
| * | ||
| * Codes in [NON_ONBOARDING_AADSTS_CODES] are filtered out the same as in the | ||
| * [MicrosoftTokenResponse] overload. | ||
| * | ||
| * @return blocking error identifier suitable for `addBlockingError(...)`, or null | ||
| */ | ||
| @JvmStatic | ||
| fun extractBlockingError(xMsCliTelemHeader: String?): String? { | ||
| if (xMsCliTelemHeader.isNullOrBlank()) return null | ||
|
|
||
| @Suppress("DEPRECATION") | ||
| val cliTelemInfo = CliTelemInfo.fromXMsCliTelemHeader(xMsCliTelemHeader) ?: return null | ||
|
|
||
| val subError = cliTelemInfo.serverSubErrorCode | ||
| if (!subError.isNullOrBlank() && subError != "0" && !isExcluded(subError)) { | ||
| return subError | ||
| } | ||
|
|
||
| val error = cliTelemInfo.serverErrorCode | ||
| if (!error.isNullOrBlank() && error != "0" && !isExcluded(error)) { | ||
| return error | ||
| } | ||
|
|
||
| return null | ||
| } | ||
|
|
||
| /** | ||
| * Extract blocking-error attribution codes from the OAuth `error_codes` query parameter | ||
| * of an authorization redirect (Microsoft extension to OAuth — comma-separated AADSTS codes, | ||
| * available on `MicrosoftStsAuthorizationErrorResponse.getErrorCodes()`). | ||
| * | ||
| * Unlike the single-value overloads (which return the most-specific identifier from the | ||
| * `x-ms-clitelem` header), eSTS frequently emits multiple AADSTS codes here when one | ||
| * authorization failure has multiple contributing causes (e.g. `"50058,53003"` = | ||
| * "no SSO session AND CA-blocked"). Returning all qualified codes lets callers add | ||
| * each via [com.microsoft.identity.common.internal.telemetry.OnboardingTelemetryRecorder.addBlockingError] | ||
| * without losing attribution detail; the schema's `blocking_errors[]` is already an array. | ||
| * | ||
| * Filters out: | ||
| * - empty entries (e.g. trailing commas) | ||
| * - the literal `"0"` (eSTS's "no error" sentinel) | ||
| * - codes in [NON_ONBOARDING_AADSTS_CODES] | ||
| * - duplicates (preserves first-occurrence order) | ||
| * | ||
| * @return ordered list of qualifying AADSTS codes; empty if none qualify | ||
| */ | ||
| @JvmStatic | ||
| fun extractBlockingErrorsFromAuthorizationErrorCodes(errorCodes: String?): List<String> { | ||
| if (errorCodes.isNullOrBlank()) return emptyList() | ||
| return errorCodes.split(",") | ||
| .map { it.trim() } | ||
| .filter { it.isNotEmpty() && it != "0" && !isExcluded(it) } | ||
| .distinct() | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.