Skip to content

Commit 7d9f5cf

Browse files
authored
[v4] Add strict matching to MSAL Interceptor (#8351)
This PR adds strict matching to MSAL Common's StringUtils, to be used in the MSAL Angular interceptor.
1 parent de0cf51 commit 7d9f5cf

9 files changed

Lines changed: 716 additions & 4 deletions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "Add strict matching to interceptor [#8351](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/8351)",
4+
"packageName": "@azure/msal-angular",
5+
"email": "joarroyo@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "Add strict matching to StringUtils [#8351](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/8351)",
4+
"packageName": "@azure/msal-common",
5+
"email": "joarroyo@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

lib/msal-angular/docs/msal-interceptor.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,43 @@ Other things to note regarding the `protectedResourceMap`:
147147
* **Wildcards**: `protectedResourceMap` supports using `*` for wildcards. When using wildcards, if multiple matching entries are found in the `protectedResourceMap`, the first match found will be used (based on the order of the `protectedResourceMap`).
148148
* **Relative paths**: If there are relative resource paths in your application, you may need to provide the relative path in the `protectedResourceMap`. This also applies to issues that may arise with ngx-translate. Be aware that the relative path in your `protectedResourceMap` may or may not need a leading slash depending on your app, and may need to try both.
149149

150+
### Strict Matching (`strictMatching`)
151+
152+
The optional `strictMatching` boolean field on `MsalInterceptorConfiguration` enables stricter, more semantically correct URL component pattern matching for `protectedResourceMap` entries. It defaults to `false` for backwards compatibility with existing applications.
153+
154+
#### What `strictMatching: true` changes
155+
156+
| Behaviour | Legacy (default) | Strict (`strictMatching: true`) |
157+
|-----------|------------------|---------------------------------|
158+
| Metacharacter escaping | `.` and other regex metacharacters are **not** escaped; they act as regex operators | All metacharacters (including `.`) are treated as **literals** |
159+
| Anchoring | Pattern may match anywhere within the string | Pattern must match the **full string** (`^…$`) |
160+
| Host wildcard (`*`) | `*` matches any character sequence, including `.` | `*` matches any character sequence that does **not** include `.` (wildcards stay within a single DNS label) |
161+
| Path/search/hash wildcard (`*`) | `*` matches any character sequence | `*` matches any character sequence (unchanged) |
162+
| `?` character | Passed through to the underlying regex | Treated as a **literal** `?` (URL query-string separator, not a wildcard) |
163+
164+
With `strictMatching: true`:
165+
- A pattern like `*.contoso.com` matches `app.contoso.com` but **not** `a.b.contoso.com` (wildcard cannot span dot separators).
166+
- A pattern like `https://graph.microsoft.com/v1.0/me` matches only that exact URL.
167+
168+
#### Enabling strict matching
169+
170+
```javascript
171+
{
172+
interactionType: InteractionType.Redirect,
173+
protectedResourceMap: new Map([
174+
["https://*.contoso.com/api", ["contoso.scope"]],
175+
["https://graph.microsoft.com/v1.0/me", ["user.read"]]
176+
]),
177+
strictMatching: true // Enable stricter, anchored pattern matching
178+
}
179+
```
180+
181+
#### Compatibility and migration
182+
183+
`strictMatching` is optional and defaults to `false` in the current release line so existing applications are unaffected. You can opt in incrementally by enabling it and reviewing your `protectedResourceMap` patterns for correctness.
184+
185+
> **Forward-looking note:** In **msal-angular v5**, `strictMatching` will be `true` by default. We recommend reviewing and updating your `protectedResourceMap` patterns to be compatible with strict matching semantics before upgrading to v5.
186+
150187
### Optional authRequest
151188

152189
For more information on the optional `authRequest` that can be set in the `MsalInterceptorConfiguration`, please see our [multi-tenant doc here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/multi-tenant.md#dynamic-auth-request).

lib/msal-angular/src/msal.interceptor.config.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ export type MsalInterceptorConfiguration = {
3131
req: HttpRequest<unknown>,
3232
originalAuthRequest: MsalInterceptorAuthRequest
3333
) => MsalInterceptorAuthRequest);
34+
/**
35+
* When `true`, enables stricter, more correct URL component pattern matching for
36+
* `protectedResourceMap` entries. Strict matching uses anchored regex patterns and
37+
* treats metacharacters (including `.`) as literals, so patterns match only their
38+
* intended strings. Wildcards still apply, but host-component wildcards
39+
* are constrained to a single DNS label.
40+
*
41+
* When `false` or omitted (default), the legacy matching behaviour is preserved for
42+
* backwards compatibility.
43+
*
44+
* **Forward-looking note:** In msal-angular v5, `strictMatching` will be `true` by
45+
* default. Applications that rely on the legacy matching behaviour should migrate to
46+
* strict matching patterns before upgrading to v5.
47+
*
48+
* @default false
49+
*/
50+
strictMatching?: boolean;
3451
};
3552

3653
export type ProtectedResourceScopes = {

0 commit comments

Comments
 (0)