Add unit tests with HTTP mocking for vanilla dSTS + fix Authority par…#3805
Merged
Conversation
Adds 7 HTTP-mocked unit tests for the vanilla dSTS (Dedicated Security Token Service) token-acquisition path in Microsoft.Identity.Web.
Per PR review feedback, dSTS users MUST configure 'Instance' (e.g. "https://{host}/dstsv2") and 'TenantId' separately. The single-string 'Authority' option is reserved for vanilla OIDC / CIAM scenarios and routes through MSAL.WithOidcAuthority(), which is incompatible with dSTS; configuring a dSTS-style URL there now throws an InvalidOperationException with a clear, actionable error message instead of letting MSAL surface its opaque "DSTS authority URI should have at least 2 segments..." error later.
Tests cover (canonical Instance + TenantId shape):
1. Token endpoint URI lock (POST to https://{host}/dstsv2/{tenant}/oauth2/v2.0/token)
2. Client_credentials grant body (grant_type, scope, client_id, client_secret)
3. Second-call cache hit (only one mock handler registered)
4. OAuth2 token-endpoint error -> MsalServiceException mapping
5. SendX5C=true -> client_assertion JWT header includes x5c
6. SendX5C=false -> x5c omitted
Plus 1 negative test:
7. Configuring dSTS URL via 'Authority' option -> InvalidOperationException with clear guidance to use Instance + TenantId
All tests use the existing MockHttpClientFactory infrastructure (no real network / Key Vault / cert) and run in any CI environment.
Implementation change in MergedOptions.ParseAuthorityIfNecessary: detects dSTS-shaped Authority (path segment "dstsv2") and throws an InvalidOperationException with a message that points users to the canonical Instance+TenantId shape. No public API changes.
eedbd53 to
c625531
Compare
cpp11nullptr
reviewed
May 7, 2026
cpp11nullptr
approved these changes
May 7, 2026
…ithub.com/AzureAD/microsoft-identity-web into zhanli1/dsts-unit-tests-with-http-mocking
cpp11nullptr
approved these changes
May 11, 2026
bgavrilMS
approved these changes
May 11, 2026
Agent-Logs-Url: https://github.com/AzureAD/microsoft-identity-web/sessions/a57b074c-3d46-4620-904a-0bfda5451eae Co-authored-by: XiaoxinMS2 <223701223+XiaoxinMS2@users.noreply.github.com>
Contributor
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
|
Contributor
Author
|
@microsoft-github-policy-service agree company="Microsoft" |
cpp11nullptr
approved these changes
May 21, 2026
This was referenced May 25, 2026
Merged
deps(nuget): Bump the microsoft-packages group with 1 update
Ellerbach/azure-ai-search-simulator#146
Merged
gunndabad
added a commit
to DFE-Digital/teaching-record-system
that referenced
this pull request
Jun 1, 2026
….0 (#3431) Updated [Microsoft.Identity.Web.GraphServiceClientBeta](https://github.com/AzureAD/microsoft-identity-web) from 4.9.0 to 4.10.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Identity.Web.GraphServiceClientBeta's releases](https://github.com/AzureAD/microsoft-identity-web/releases)._ ## 4.10.0 ### New features - Add `WithExtraBodyParameters` fluent API for attaching extra body parameters to token acquisition requests. See [#3819](AzureAD/microsoft-identity-web#3819). - Add `IConfidentialClientApplicationProvider` extensibility interface and `CachePartitionKey` support for silent token acquisition. See [#3822](AzureAD/microsoft-identity-web#3822). ### Bug fixes - Redirect URI sanitization in authorization scenarios; centralize redirect URI validation in a shared helper. See [#3825](AzureAD/microsoft-identity-web#3825). - Reject dSTS-shaped `Authority` values with a clearer exception, steering users to use `Instance` + `TenantId` instead. See [#3805](AzureAD/microsoft-identity-web#3805). - Improve regex handling and adding length/timeout safeguards for SameSite User Agent. See [#3811](AzureAD/microsoft-identity-web#3811). ### Behavior changes - **B2C OpenID Connect event handler: LRU cache for issuer address.** Issuer address lookups in the B2C OIDC event handler are now cached with an LRU cache, improving performance for repeated lookups. See [#3821](AzureAD/microsoft-identity-web#3821). ### Dependencies updates - Update MSAL.NET to 4.84.1. See [#3822](AzureAD/microsoft-identity-web#3822). - Pin `Microsoft.Kiota.Abstractions` to 1.22.0 for GraphServiceClient. See [#3817](AzureAD/microsoft-identity-web#3817). - Bump `uuid` and `@azure/msal-node` in SidecarAdapter TypeScript test app. See [#3826](AzureAD/microsoft-identity-web#3826). - Bump `qs` in SidecarAdapter TypeScript test app. See [#3829](AzureAD/microsoft-identity-web#3829). Commits viewable in [compare view](AzureAD/microsoft-identity-web@4.9.0...4.10.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Gunn <james@gunn.io>
This was referenced Jun 1, 2026
Merged
Open
gunndabad
added a commit
to DFE-Digital/teaching-record-system
that referenced
this pull request
Jun 4, 2026
Updated [Microsoft.Identity.Web](https://github.com/AzureAD/microsoft-identity-web) from 4.7.0 to 4.10.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Identity.Web's releases](https://github.com/AzureAD/microsoft-identity-web/releases)._ ## 4.10.0 ### New features - Add `WithExtraBodyParameters` fluent API for attaching extra body parameters to token acquisition requests. See [#3819](AzureAD/microsoft-identity-web#3819). - Add `IConfidentialClientApplicationProvider` extensibility interface and `CachePartitionKey` support for silent token acquisition. See [#3822](AzureAD/microsoft-identity-web#3822). ### Bug fixes - Redirect URI sanitization in authorization scenarios; centralize redirect URI validation in a shared helper. See [#3825](AzureAD/microsoft-identity-web#3825). - Reject dSTS-shaped `Authority` values with a clearer exception, steering users to use `Instance` + `TenantId` instead. See [#3805](AzureAD/microsoft-identity-web#3805). - Improve regex handling and adding length/timeout safeguards for SameSite User Agent. See [#3811](AzureAD/microsoft-identity-web#3811). ### Behavior changes - **B2C OpenID Connect event handler: LRU cache for issuer address.** Issuer address lookups in the B2C OIDC event handler are now cached with an LRU cache, improving performance for repeated lookups. See [#3821](AzureAD/microsoft-identity-web#3821). ### Dependencies updates - Update MSAL.NET to 4.84.1. See [#3822](AzureAD/microsoft-identity-web#3822). - Pin `Microsoft.Kiota.Abstractions` to 1.22.0 for GraphServiceClient. See [#3817](AzureAD/microsoft-identity-web#3817). - Bump `uuid` and `@azure/msal-node` in SidecarAdapter TypeScript test app. See [#3826](AzureAD/microsoft-identity-web#3826). - Bump `qs` in SidecarAdapter TypeScript test app. See [#3829](AzureAD/microsoft-identity-web#3829). ## 4.9.0 ### New features - **Sidecar: per-route override gating.** New `Sidecar:AllowOverrides` configuration section provides explicit, per-route control over whether `optionsOverride.*` query-string parameters are honored. Authenticated routes default to allowing overrides (preserving existing behavior); unauthenticated routes default to rejecting them. `optionsOverride.BaseUrl` is unconditionally rejected on all routes as a hardening measure. See [#3794](AzureAD/microsoft-identity-web#3794). ### Bug fixes - Fix `AccountController.Challenge` redirect URI validation to reject percent-encoded protocol-relative bypasses (`%2F%2F`, `%5C%2F`, etc.) that could be decoded by misconfigured reverse proxies. See [#3792](AzureAD/microsoft-identity-web#3792). ### Behavior changes - **DownstreamApi: reserved header filtering.** Headers supplied via `DownstreamApiOptions.ExtraHeaderParameters` whose names match reserved HTTP headers (`Authorization`, `Host`, `Content-Length`, `Proxy-Authorization`, `Sec-*`, `Proxy-*`, etc.) or duplicate a header the library already set are now silently skipped. A warning-level log entry (`ReservedHeaderIgnored` / `DuplicateHeaderIgnored`) is emitted so operators can spot misconfigurations. No exception is thrown. See [#3793](AzureAD/microsoft-identity-web#3793). ### Dependencies updates - **Update Azure.Identity 1.11.4 → 1.17.2 and establish Microsoft.Extensions.\* 8.0.x minimum on older TFMs.** Azure.Identity 1.17.2 (sovereign-cloud fixes) pulls in Azure.Core 1.50.0, which introduces a transitive dependency on `Microsoft.Extensions.DependencyInjection.Abstractions` 8.0.2 on non-framework-coupled TFMs (net462, net472, netstandard2.0). This caused a `CS0433` type collision with the previously-pinned `Microsoft.Extensions.DependencyInjection` 2.1.0. Rather than patch individual packages, the entire `Microsoft.Extensions.*` stack on these older TFMs has been bumped to 8.0.x, closing several 5-year version gaps and aligning with the net8.0 baseline. **If your application targets net462, net472, or netstandard2.0**, your resolved `Microsoft.Extensions.*` versions will increase (e.g., `Extensions.Http` 3.1.3 → 8.0.0, `Extensions.DependencyInjection` 2.1.0 → 8.0.0, `Extensions.Caching.Memory` 2.1.0/6.0.2 → 8.0.1). Applications already targeting net8.0+ are unaffected. See [#3787](AzureAD/microsoft-identity-web#3787). - Bump `System.Text.Json` 8.0.5 → 8.0.6 (CVE-2024-43485). See [#3787](AzureAD/microsoft-identity-web#3787). - Bump `Microsoft.AspNetCore.DataProtection` to 10.0.7 for CVE fix on net10.0. See [#3796](AzureAD/microsoft-identity-web#3796). - Bump `OpenTelemetry.Exporter.OpenTelemetryProtocol` 1.14.0 → 1.15.3. See [#3788](AzureAD/microsoft-identity-web#3788). **Full Changelog**: AzureAD/microsoft-identity-web@4.8.0...4.9.0 ## 4.8.0 ## What's Changed * Bump flatted from 3.3.3 to 3.4.2 in /tests/DevApps/SidecarAdapter/typescript by @dependabot[bot] in AzureAD/microsoft-identity-web#3753 * Update changelog.md for ID.Web 4.6.0 by @bgavrilMS in AzureAD/microsoft-identity-web#3756 * Add token binding to MicrosoftIdentityMessageHandler by @cpp11nullptr in AzureAD/microsoft-identity-web#3743 * Bump picomatch in /tests/DevApps/SidecarAdapter/typescript by @dependabot[bot] in AzureAD/microsoft-identity-web#3759 * Documentation: Clarify managed identity credential types for containerized vs. VM/App Service deployments by @Copilot in AzureAD/microsoft-identity-web#3585 * Bump path-to-regexp from 8.3.0 to 8.4.0 in /tests/DevApps/SidecarAdapter/typescript by @dependabot[bot] in AzureAD/microsoft-identity-web#3762 * Upgrade Microsoft Application Insights packages by @RojaEnnam in AzureAD/microsoft-identity-web#3763 * Use Abstractions 12 by @pmaytak in AzureAD/microsoft-identity-web#3761 * Post-4.7.0 by @pmaytak in AzureAD/microsoft-identity-web#3768 * Fix Comp Gov DOTNET-Security-10.0 by @reginayap8 in AzureAD/microsoft-identity-web#3769 * Upgrade CodeQL to V4: Fix 10 CodeQL Analysis Warnings and Errors by @reginayap8 in AzureAD/microsoft-identity-web#3770 * fix warnings by @gladjohn in AzureAD/microsoft-identity-web#3771 * adding examples for using postgres as a distributed cache by @JaredMSFT in AzureAD/microsoft-identity-web#3766 * Suppress AOT configuration-binding SYSLIB warnings in AotCompatibility test app by @Copilot in AzureAD/microsoft-identity-web#3774 * Bump vite from 7.1.11 to 7.3.2 in /tests/DevApps/SidecarAdapter/typescript by @dependabot[bot] in AzureAD/microsoft-identity-web#3772 * Skip legacy B2C local-account Todo UI test in WebAppUiTests by @Copilot in AzureAD/microsoft-identity-web#3778 * Fix initialization of ConfidentialClientApplicationOptions in MergedOptions by @cpp11nullptr in AzureAD/microsoft-identity-web#3760 * Bump net8/net9/net10 runtime package baselines to patched crypto servicing versions by @Copilot in AzureAD/microsoft-identity-web#3779 * Fix flaky certificate test failures on CI by @gladjohn in AzureAD/microsoft-identity-web#3780 * MTLS Without Tokens Support by @tlupes in AzureAD/microsoft-identity-web#3747 * Fix CredentialsProvider DI lifetime mismatch causing startup crash in Development by @Avery-Dunn in AzureAD/microsoft-identity-web#3783 * Remove unused DataProtection configuration from Sidecar by @Copilot in AzureAD/microsoft-identity-web#3776 ## New Contributors * @RojaEnnam made their first contribution in AzureAD/microsoft-identity-web#3763 * @reginayap8 made their first contribution in AzureAD/microsoft-identity-web#3769 * @JaredMSFT made their first contribution in AzureAD/microsoft-identity-web#3766 **Full Changelog**: AzureAD/microsoft-identity-web@4.6.0...4.8.0 Commits viewable in [compare view](AzureAD/microsoft-identity-web@4.7.0...4.10.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Gunn <james@gunn.io>
This was referenced Jun 5, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
…sing
Adds 6 HTTP-mocked unit tests for the vanilla dSTS (Dedicated Security Token Service) token-acquisition path in Microsoft.Identity.Web, and fixes MergedOptions.ParseAuthorityIfNecessary so that the natural / documented dSTS configuration form works end-to-end:
Without the fix, the AAD-style parser took the literal "dstsv2" as the tenant and dropped the actual tenant GUID, producing an authority MSAL rejected with "The DSTS authority URI should have at least 2 segments...".
Tests cover: token endpoint URI; client_credentials grant body; second-call cache hit; OAuth2 error -> MsalServiceException mapping; SendX5C=true includes x5c JWT header; SendX5C=false omits it. All tests use the existing MockHttpClientFactory infrastructure (no real network / Key Vault / cert) and run in any CI environment.
No public API changes.
Add unit tests with HTTP mocking for vanilla dSTS scenarios + fix
Authority-only configurationSummary of the changes (Less than 80 chars)
Description
Adds 6 HTTP-mocked unit tests covering the vanilla dSTS (Dedicated Security Token Service) token-acquisition path in Microsoft.Identity.Web, and fixes a parser bug in
MergedOptions.ParseAuthorityIfNecessarythat prevented the natural / documented dSTS configuration form (options.Authority = "https://{host}/dstsv2/{tenantGuid}") from working.Both changes ship together because the new tests use the natural configuration form, which is the form the parser fix unblocks.
Vanilla dSTS support in Id.Web previously had zero unit-test coverage — the only assertion lived in integration tests that required a real dSTS deployment + Key Vault certificate, so they couldn't run in CI. Anyone refactoring
MergedOptions/TokenAcquirerFactorycould silently break dSTS token acquisition without any signal.Fixes #{bug number} (in this specific format)