Add NativeAuthRequestInterceptor for custom per-request HTTP headers, Fixes AB#3606613#2511
Conversation
Wire the NativeAuthRequestInterceptor through MSAL's public configuration and command parameters adapter, matching the iOS PR (microsoft-authentication-library-for-objc#2862). - Add requestInterceptor property to NativeAuthPublicClientApplicationConfiguration - Propagate interceptor in all 16 native auth CommandParametersAdapter builder calls - Update common submodule to spetrescu/custom_headers branch - Fix pre-existing duplicate .challengeType() call in createSignInResendCodeCommandParameters() Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
❌ Work item link check failed. Description does not contain AB#{ID}. Click here to Learn more. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds native auth support for per-request custom HTTP headers by introducing a request interceptor on native auth configuration and propagating it into native auth command parameters.
Changes:
- Added a transient
requestInterceptorproperty toNativeAuthPublicClientApplicationConfigurationand included it in configuration merging. - Propagated
requestInterceptorthrough most native auth command parameter builders. - Removed a duplicate
challengeType()call in sign-in resend-code parameter construction.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
msal/src/main/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationConfiguration.kt |
Adds the native auth request interceptor configuration field and merge behavior. |
msal/src/main/java/com/microsoft/identity/client/internal/CommandParametersAdapter.java |
Passes the configured interceptor into native auth command parameter builders. |
Update comment
…/microsoft-authentication-library-for-android into spetrescu/custom_headers
|
@copilot apply changes based on the comments in this thread |
…eAuthPublicClientApplicationParameters Agent-Logs-Url: https://github.com/AzureAD/microsoft-authentication-library-for-android/sessions/3e578494-fa53-4d9a-92cc-5f88b974f149 Co-authored-by: spetrescu84 <111577419+spetrescu84@users.noreply.github.com>
Applied both fixes in commit d6bb35a:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| .challengeType(configuration.getChallengeTypes()) | ||
| .requestInterceptor(configuration.getRequestInterceptor()) | ||
| .continuationToken(continuationToken) | ||
| .challengeType(configuration.getChallengeTypes()) |
There was a problem hiding this comment.
This was removed because it's duplicated above
| import com.microsoft.identity.nativeauth.NativeAuthPublicClientApplication; | ||
| import com.microsoft.identity.nativeauth.NativeAuthPublicClientApplicationConfiguration; | ||
| import com.microsoft.identity.nativeauth.NativeAuthPublicClientApplicationParameters; | ||
| import com.microsoft.identity.common.java.nativeauth.providers.NativeAuthRequestInterceptor; |
There was a problem hiding this comment.
@spetrescu84 we should not import common core in public api
Define NativeAuthRequestInterceptor in com.microsoft.identity.nativeauth so that sample apps and customers import from the MSAL public API package instead of directly from common. This follows the established pattern where all public-facing nativeauth types (AuthMethod, RequiredUserAttribute, INativeAuthPublicClientApplication, etc.) live in the MSAL module. The interface extends OAuth2RequestInterceptor from common, maintaining full compatibility with common's internal usage of the base type. Updates common submodule to use OAuth2RequestInterceptor internally. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
-added Native Auth Sample App to Android Manifest
| * (which sets custom headers via NativeAuthRequestInterceptor on the initiate call), | ||
| * enters credentials from the lab vault, and attempts sign-in. | ||
| */ | ||
| class NativeAuthSignInTest : AbstractCrossAppUiTest() { |
There was a problem hiding this comment.
Could we rename to reflect type of test and purpose of it? Like NativeAuthSignInWithCustomHeadersUiTest or NativeAuthSignInUiTest.
There was a problem hiding this comment.
Updated to NativeAuthSignInUIAutomationTest as it's an UI Automation test. The class will have other sign in tests so only the name of the test will highlight what the test does.
There was a problem hiding this comment.
Good catch, merge conflict incorrectly solved. Renamed file to match
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Explicitly cast to String to resolve Kotlin overload resolution between pkg(Pattern) and pkg(String). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| // An optional interceptor that is called before each native auth network request, allowing the application to inject custom HTTP header fields. | ||
| // Refer to [NativeAuthRequestInterceptor] for more details. | ||
| @Transient | ||
| var requestInterceptor: NativeAuthRequestInterceptor? = null |
There was a problem hiding this comment.
The developer sets class they are working from as a NativeAuthRequestInterceptor, then after creating the INativeAuthPublicClientApplication the developer sets it like this:
(authClient as? PublicClientApplication)?.let { app ->
(app.configuration as? NativeAuthPublicClientApplicationConfiguration)?.requestInterceptor = this
}
and they set they override this function:
override fun additionalHeaders(requestUrl: URL): Map<String, String>? {
if (requestUrl.path.contains("oauth2/v2.0/initiate")) {
return mapOf(
"ignored-custom-header-value" to "ignored-custom-header", // Will be ignored: doesn't start with "x-"
"x-client-header" to "customer_header_2", // Will be ignored: starts with reserved prefix "x-client-"
"X-my-custom-header" to "my data" // Will be added to the network request
)
}
return null
}
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When release-integration/8.3.3 was back-merged into dev (#2520), entry #2511 (which was merged to dev *after* the 8.3.3 RC cut) got listed under `Version 8.3.3`. It actually shipped to dev after 8.3.3 was finalized, so it belongs under `vNext` for the next release. This PR moves 1 entry from `Version 8.3.3` to `vNext`: - #2511 Provide public api to set custom headers for CIAM requests ### Verification Identified by diffing the current dev `changelog` against the file at commit `12b16091c` (final 8.3.3 "remove RC" cut). [AB#3618269](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3618269) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Enables apps to inject custom
x-*headers into native auth HTTP requests (e.g., for CIAM fraud-signal scenarios like Akamai sensor data).Changes
MSAL (this PR)
NativeAuthRequestInterceptor.kt— Defined incom.microsoft.identity.nativeauthpackage (public API for customers to implement)NativeAuthPublicClientApplicationConfiguration.kt— Added@Transient var requestInterceptorproperty withmergeConfigurationsupportNativeAuthPublicClientApplicationParameters.kt— Exposes interceptor using the MSAL-level typePublicClientApplication.java— Updated import to use MSAL-levelNativeAuthRequestInterceptorCommandParametersAdapter.java— PropagatedrequestInterceptorthrough all 16 native auth builder calls; fixed pre-existing duplicate.challengeType()increateSignInResendCodeCommandParameters()UI Automation Tests (this PR)
AbstractCrossAppUiTest.java— Lightweight base class for cross-app UI tests (providesmDevice,mLabClient,CopyFileRule, uninstall/reinstall of target app). Avoids the heavyRulesHelperchain that causes SIGKILL in cross-app scenarios.NativeAuthSignInTest.kt— End-to-end sign-in test using CIAM tenant with custom headers on the initiate endpoint. Gets credentials from lab vault, launches NativeAuthSampleApp with injected config, and verifies sign-in completes successfully.AndroidManifest.xml— Added<queries>block for NativeAuthSampleApp package (required on Android 11+ forgetLaunchIntentForPackage())Common (spetrescu/custom_headers)
NativeAuthHeaderValidator.kt— Validates headers (must start withx-, must NOT start withx-ms-,x-client-,x-broker-,x-app-)OAuth2RequestInterceptorbase typeapplyInterceptorHeaders()before everyhttpClient.post()call in all 4 interactorsArchitecture Decision: Interface Placement
NativeAuthRequestInterceptoris defined in MSAL (com.microsoft.identity.nativeauth) following the established pattern where all public-facing nativeauth types live in the MSAL module. Common uses the parentOAuth2RequestInterceptortype internally. This ensures sample apps and customers never need to import fromcom.microsoft.identity.common.*.Testing
NativeAuthHeaderValidator(all validation scenarios)RequestInterceptorHeaderUtilsTestfor merge logicNativeAuthSignInTest— E2E UI automation test (sign-in with custom headers via CIAM tenant)Design Decisions
challengeTypes/capabilitiesfor consistency@Transienton config field — set programmatically, not from JSONcom.microsoft.identity.nativeauth, not commonAB#3606613