@azure/msal-common 16.11.3 → 16.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/dist/account/AccountInfo.mjs +1 -1
  2. package/dist/account/AuthToken.mjs +1 -1
  3. package/dist/account/CcsCredential.mjs +1 -1
  4. package/dist/account/ClientInfo.mjs +1 -1
  5. package/dist/account/TokenClaims.mjs +1 -1
  6. package/dist/authority/Authority.mjs +1 -1
  7. package/dist/authority/AuthorityFactory.mjs +1 -1
  8. package/dist/authority/AuthorityMetadata.mjs +2 -5
  9. package/dist/authority/AuthorityMetadata.mjs.map +1 -1
  10. package/dist/authority/AuthorityOptions.mjs +1 -1
  11. package/dist/authority/AuthorityType.mjs +1 -1
  12. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  13. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  14. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  15. package/dist/authority/ProtocolMode.mjs +1 -1
  16. package/dist/authority/RegionDiscovery.mjs +1 -1
  17. package/dist/cache/CacheManager.mjs +55 -19
  18. package/dist/cache/CacheManager.mjs.map +1 -1
  19. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  20. package/dist/cache/utils/AccountEntityUtils.mjs +1 -1
  21. package/dist/cache/utils/CacheHelpers.mjs +24 -4
  22. package/dist/cache/utils/CacheHelpers.mjs.map +1 -1
  23. package/dist/client/AuthorizationCodeClient.mjs +10 -4
  24. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  25. package/dist/client/RefreshTokenClient.mjs +10 -4
  26. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  27. package/dist/client/SilentFlowClient.mjs +5 -2
  28. package/dist/client/SilentFlowClient.mjs.map +1 -1
  29. package/dist/config/ClientConfiguration.mjs +4 -2
  30. package/dist/config/ClientConfiguration.mjs.map +1 -1
  31. package/dist/constants/AADServerParamKeys.mjs +4 -3
  32. package/dist/constants/AADServerParamKeys.mjs.map +1 -1
  33. package/dist/crypto/ICrypto.mjs +16 -11
  34. package/dist/crypto/ICrypto.mjs.map +1 -1
  35. package/dist/crypto/ITokenBindingKeyManager.mjs +28 -0
  36. package/dist/crypto/ITokenBindingKeyManager.mjs.map +1 -0
  37. package/dist/crypto/JoseHeader.mjs +38 -11
  38. package/dist/crypto/JoseHeader.mjs.map +1 -1
  39. package/dist/crypto/PopTokenGenerator.mjs +28 -5
  40. package/dist/crypto/PopTokenGenerator.mjs.map +1 -1
  41. package/dist/error/AuthError.mjs +1 -1
  42. package/dist/error/AuthErrorCodes.mjs +1 -1
  43. package/dist/error/CacheError.mjs +1 -1
  44. package/dist/error/CacheErrorCodes.mjs +1 -1
  45. package/dist/error/ClientAuthError.mjs +1 -1
  46. package/dist/error/ClientAuthErrorCodes.mjs +1 -1
  47. package/dist/error/ClientConfigurationError.mjs +1 -1
  48. package/dist/error/ClientConfigurationErrorCodes.mjs +3 -2
  49. package/dist/error/ClientConfigurationErrorCodes.mjs.map +1 -1
  50. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  51. package/dist/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
  52. package/dist/error/JoseHeaderError.mjs +1 -1
  53. package/dist/error/JoseHeaderErrorCodes.mjs +5 -3
  54. package/dist/error/JoseHeaderErrorCodes.mjs.map +1 -1
  55. package/dist/error/NetworkError.mjs +1 -1
  56. package/dist/error/PlatformBrokerError.mjs +1 -1
  57. package/dist/error/ServerError.mjs +1 -1
  58. package/dist/index-node.mjs +3 -2
  59. package/dist/index-node.mjs.map +1 -1
  60. package/dist/index.mjs +3 -2
  61. package/dist/index.mjs.map +1 -1
  62. package/dist/logger/Logger.mjs +1 -1
  63. package/dist/network/INetworkModule.mjs +1 -1
  64. package/dist/network/RequestThumbprint.mjs +4 -1
  65. package/dist/network/RequestThumbprint.mjs.map +1 -1
  66. package/dist/network/ThrottlingUtils.mjs +1 -1
  67. package/dist/packageMetadata.mjs +2 -2
  68. package/dist/protocol/Authorize.mjs +1 -1
  69. package/dist/protocol/Token.mjs +1 -1
  70. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  71. package/dist/request/BaseAuthRequest.mjs +1 -1
  72. package/dist/request/BaseAuthRequest.mjs.map +1 -1
  73. package/dist/request/RequestParameterBuilder.mjs +94 -26
  74. package/dist/request/RequestParameterBuilder.mjs.map +1 -1
  75. package/dist/request/ScopeSet.mjs +1 -1
  76. package/dist/response/ResponseHandler.mjs +30 -8
  77. package/dist/response/ResponseHandler.mjs.map +1 -1
  78. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  79. package/dist/telemetry/performance/PerformanceEvent.mjs +1 -1
  80. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  81. package/dist/telemetry/performance/PerformanceEvents.mjs +1 -1
  82. package/dist/telemetry/performance/StubPerformanceClient.mjs +1 -1
  83. package/dist/telemetry/server/ServerTelemetryManager.mjs +1 -1
  84. package/dist/url/UrlString.mjs +1 -1
  85. package/dist/utils/ClientAssertionUtils.mjs +1 -1
  86. package/dist/utils/Constants.mjs +2 -1
  87. package/dist/utils/Constants.mjs.map +1 -1
  88. package/dist/utils/FunctionWrappers.mjs +1 -1
  89. package/dist/utils/ObjectUtils.mjs +28 -0
  90. package/dist/utils/ObjectUtils.mjs.map +1 -0
  91. package/dist/utils/ProtocolUtils.mjs +1 -1
  92. package/dist/utils/StringUtils.mjs +1 -1
  93. package/dist/utils/TimeUtils.mjs +1 -1
  94. package/dist/utils/UrlUtils.mjs +1 -1
  95. package/dist-browser/account/AccountInfo.mjs +1 -1
  96. package/dist-browser/account/AuthToken.mjs +1 -1
  97. package/dist-browser/account/CcsCredential.mjs +1 -1
  98. package/dist-browser/account/ClientInfo.mjs +1 -1
  99. package/dist-browser/account/TokenClaims.mjs +1 -1
  100. package/dist-browser/authority/Authority.mjs +1 -1
  101. package/dist-browser/authority/AuthorityFactory.mjs +1 -1
  102. package/dist-browser/authority/AuthorityMetadata.mjs +2 -5
  103. package/dist-browser/authority/AuthorityMetadata.mjs.map +1 -1
  104. package/dist-browser/authority/AuthorityOptions.mjs +1 -1
  105. package/dist-browser/authority/AuthorityType.mjs +1 -1
  106. package/dist-browser/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  107. package/dist-browser/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  108. package/dist-browser/authority/OpenIdConfigResponse.mjs +1 -1
  109. package/dist-browser/authority/ProtocolMode.mjs +1 -1
  110. package/dist-browser/authority/RegionDiscovery.mjs +1 -1
  111. package/dist-browser/cache/CacheManager.mjs +55 -19
  112. package/dist-browser/cache/CacheManager.mjs.map +1 -1
  113. package/dist-browser/cache/persistence/TokenCacheContext.mjs +1 -1
  114. package/dist-browser/cache/utils/AccountEntityUtils.mjs +1 -1
  115. package/dist-browser/cache/utils/CacheHelpers.mjs +24 -4
  116. package/dist-browser/cache/utils/CacheHelpers.mjs.map +1 -1
  117. package/dist-browser/client/AuthorizationCodeClient.mjs +10 -4
  118. package/dist-browser/client/AuthorizationCodeClient.mjs.map +1 -1
  119. package/dist-browser/client/RefreshTokenClient.mjs +10 -4
  120. package/dist-browser/client/RefreshTokenClient.mjs.map +1 -1
  121. package/dist-browser/client/SilentFlowClient.mjs +5 -2
  122. package/dist-browser/client/SilentFlowClient.mjs.map +1 -1
  123. package/dist-browser/config/ClientConfiguration.mjs +4 -2
  124. package/dist-browser/config/ClientConfiguration.mjs.map +1 -1
  125. package/dist-browser/constants/AADServerParamKeys.mjs +4 -3
  126. package/dist-browser/constants/AADServerParamKeys.mjs.map +1 -1
  127. package/dist-browser/crypto/ICrypto.mjs +16 -11
  128. package/dist-browser/crypto/ICrypto.mjs.map +1 -1
  129. package/dist-browser/crypto/ITokenBindingKeyManager.mjs +28 -0
  130. package/dist-browser/crypto/ITokenBindingKeyManager.mjs.map +1 -0
  131. package/dist-browser/crypto/JoseHeader.mjs +38 -11
  132. package/dist-browser/crypto/JoseHeader.mjs.map +1 -1
  133. package/dist-browser/crypto/PopTokenGenerator.mjs +28 -5
  134. package/dist-browser/crypto/PopTokenGenerator.mjs.map +1 -1
  135. package/dist-browser/error/AuthError.mjs +1 -1
  136. package/dist-browser/error/AuthErrorCodes.mjs +1 -1
  137. package/dist-browser/error/CacheError.mjs +1 -1
  138. package/dist-browser/error/CacheErrorCodes.mjs +1 -1
  139. package/dist-browser/error/ClientAuthError.mjs +1 -1
  140. package/dist-browser/error/ClientAuthErrorCodes.mjs +1 -1
  141. package/dist-browser/error/ClientConfigurationError.mjs +1 -1
  142. package/dist-browser/error/ClientConfigurationErrorCodes.mjs +3 -2
  143. package/dist-browser/error/ClientConfigurationErrorCodes.mjs.map +1 -1
  144. package/dist-browser/error/InteractionRequiredAuthError.mjs +1 -1
  145. package/dist-browser/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
  146. package/dist-browser/error/JoseHeaderError.mjs +1 -1
  147. package/dist-browser/error/JoseHeaderErrorCodes.mjs +5 -3
  148. package/dist-browser/error/JoseHeaderErrorCodes.mjs.map +1 -1
  149. package/dist-browser/error/NetworkError.mjs +1 -1
  150. package/dist-browser/error/PlatformBrokerError.mjs +1 -1
  151. package/dist-browser/error/ServerError.mjs +1 -1
  152. package/dist-browser/index-browser.mjs +3 -2
  153. package/dist-browser/index-browser.mjs.map +1 -1
  154. package/dist-browser/index.mjs +3 -2
  155. package/dist-browser/index.mjs.map +1 -1
  156. package/dist-browser/log-strings-mapping.json +2 -2
  157. package/dist-browser/logger/Logger.mjs +1 -1
  158. package/dist-browser/network/INetworkModule.mjs +1 -1
  159. package/dist-browser/network/RequestThumbprint.mjs +4 -1
  160. package/dist-browser/network/RequestThumbprint.mjs.map +1 -1
  161. package/dist-browser/network/ThrottlingUtils.mjs +1 -1
  162. package/dist-browser/packageMetadata.mjs +2 -2
  163. package/dist-browser/protocol/Authorize.mjs +1 -1
  164. package/dist-browser/protocol/Token.mjs +1 -1
  165. package/dist-browser/request/AuthenticationHeaderParser.mjs +1 -1
  166. package/dist-browser/request/BaseAuthRequest.mjs +1 -1
  167. package/dist-browser/request/BaseAuthRequest.mjs.map +1 -1
  168. package/dist-browser/request/RequestParameterBuilder.mjs +94 -26
  169. package/dist-browser/request/RequestParameterBuilder.mjs.map +1 -1
  170. package/dist-browser/request/ScopeSet.mjs +1 -1
  171. package/dist-browser/response/ResponseHandler.mjs +30 -8
  172. package/dist-browser/response/ResponseHandler.mjs.map +1 -1
  173. package/dist-browser/telemetry/performance/PerformanceClient.mjs +1 -1
  174. package/dist-browser/telemetry/performance/PerformanceEvent.mjs +1 -1
  175. package/dist-browser/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  176. package/dist-browser/telemetry/performance/PerformanceEvents.mjs +1 -1
  177. package/dist-browser/telemetry/performance/StubPerformanceClient.mjs +1 -1
  178. package/dist-browser/telemetry/server/ServerTelemetryManager.mjs +1 -1
  179. package/dist-browser/url/UrlString.mjs +1 -1
  180. package/dist-browser/utils/ClientAssertionUtils.mjs +1 -1
  181. package/dist-browser/utils/Constants.mjs +2 -1
  182. package/dist-browser/utils/Constants.mjs.map +1 -1
  183. package/dist-browser/utils/FunctionWrappers.mjs +1 -1
  184. package/dist-browser/utils/ObjectUtils.mjs +28 -0
  185. package/dist-browser/utils/ObjectUtils.mjs.map +1 -0
  186. package/dist-browser/utils/ProtocolUtils.mjs +1 -1
  187. package/dist-browser/utils/StringUtils.mjs +1 -1
  188. package/dist-browser/utils/TimeUtils.mjs +1 -1
  189. package/dist-browser/utils/UrlUtils.mjs +1 -1
  190. package/lib/index-browser.cjs +5 -67
  191. package/lib/index-browser.cjs.map +1 -1
  192. package/lib/{index-node-JVUj78ag.js → index-node-BaODPZEy.js} +404 -75
  193. package/lib/index-node-BaODPZEy.js.map +1 -0
  194. package/lib/index-node.cjs +4 -2
  195. package/lib/index-node.cjs.map +1 -1
  196. package/lib/index.cjs +5 -3
  197. package/lib/index.cjs.map +1 -1
  198. package/package.json +1 -1
  199. package/src/authority/AuthorityMetadata.ts +1 -4
  200. package/src/cache/CacheManager.ts +100 -29
  201. package/src/cache/interface/ICacheManager.ts +7 -4
  202. package/src/cache/utils/CacheHelpers.ts +28 -1
  203. package/src/client/AuthorizationCodeClient.ts +16 -1
  204. package/src/client/RefreshTokenClient.ts +16 -1
  205. package/src/client/SilentFlowClient.ts +4 -1
  206. package/src/config/ClientConfiguration.ts +10 -0
  207. package/src/constants/AADServerParamKeys.ts +1 -0
  208. package/src/crypto/DpopProofGenerator.ts +52 -59
  209. package/src/crypto/ICrypto.ts +31 -26
  210. package/src/crypto/ITokenBindingKeyManager.ts +84 -0
  211. package/src/crypto/JoseHeader.ts +74 -14
  212. package/src/crypto/PopTokenGenerator.ts +62 -18
  213. package/src/error/ClientConfigurationErrorCodes.ts +2 -0
  214. package/src/error/JoseHeaderErrorCodes.ts +2 -0
  215. package/src/exports-common.ts +7 -0
  216. package/src/network/RequestThumbprint.ts +5 -0
  217. package/src/packageMetadata.ts +1 -1
  218. package/src/request/BaseAuthRequest.ts +4 -0
  219. package/src/request/RequestParameterBuilder.ts +119 -26
  220. package/src/response/ResponseHandler.ts +56 -15
  221. package/src/telemetry/performance/PerformanceEvent.ts +15 -0
  222. package/src/utils/Constants.ts +1 -0
  223. package/src/utils/ObjectUtils.ts +31 -0
  224. package/types/authority/AuthorityMetadata.d.ts.map +1 -1
  225. package/types/cache/CacheManager.d.ts +14 -7
  226. package/types/cache/CacheManager.d.ts.map +1 -1
  227. package/types/cache/interface/ICacheManager.d.ts +6 -4
  228. package/types/cache/interface/ICacheManager.d.ts.map +1 -1
  229. package/types/cache/utils/CacheHelpers.d.ts +7 -0
  230. package/types/cache/utils/CacheHelpers.d.ts.map +1 -1
  231. package/types/client/AuthorizationCodeClient.d.ts.map +1 -1
  232. package/types/client/RefreshTokenClient.d.ts.map +1 -1
  233. package/types/client/SilentFlowClient.d.ts.map +1 -1
  234. package/types/config/ClientConfiguration.d.ts +5 -1
  235. package/types/config/ClientConfiguration.d.ts.map +1 -1
  236. package/types/constants/AADServerParamKeys.d.ts +1 -0
  237. package/types/constants/AADServerParamKeys.d.ts.map +1 -1
  238. package/types/crypto/DpopProofGenerator.d.ts +10 -36
  239. package/types/crypto/DpopProofGenerator.d.ts.map +1 -1
  240. package/types/crypto/ICrypto.d.ts +10 -9
  241. package/types/crypto/ICrypto.d.ts.map +1 -1
  242. package/types/crypto/ITokenBindingKeyManager.d.ts +41 -0
  243. package/types/crypto/ITokenBindingKeyManager.d.ts.map +1 -0
  244. package/types/crypto/JoseHeader.d.ts +17 -5
  245. package/types/crypto/JoseHeader.d.ts.map +1 -1
  246. package/types/crypto/PopTokenGenerator.d.ts +3 -1
  247. package/types/crypto/PopTokenGenerator.d.ts.map +1 -1
  248. package/types/error/ClientConfigurationErrorCodes.d.ts +1 -0
  249. package/types/error/ClientConfigurationErrorCodes.d.ts.map +1 -1
  250. package/types/error/JoseHeaderErrorCodes.d.ts +2 -0
  251. package/types/error/JoseHeaderErrorCodes.d.ts.map +1 -1
  252. package/types/exports-common.d.ts +3 -2
  253. package/types/exports-common.d.ts.map +1 -1
  254. package/types/network/RequestThumbprint.d.ts +1 -0
  255. package/types/network/RequestThumbprint.d.ts.map +1 -1
  256. package/types/packageMetadata.d.ts +1 -1
  257. package/types/request/BaseAuthRequest.d.ts +4 -0
  258. package/types/request/BaseAuthRequest.d.ts.map +1 -1
  259. package/types/request/RequestParameterBuilder.d.ts +22 -4
  260. package/types/request/RequestParameterBuilder.d.ts.map +1 -1
  261. package/types/response/ResponseHandler.d.ts +12 -2
  262. package/types/response/ResponseHandler.d.ts.map +1 -1
  263. package/types/telemetry/performance/PerformanceEvent.d.ts +12 -0
  264. package/types/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  265. package/types/utils/Constants.d.ts +1 -0
  266. package/types/utils/Constants.d.ts.map +1 -1
  267. package/types/utils/ObjectUtils.d.ts +6 -0
  268. package/types/utils/ObjectUtils.d.ts.map +1 -0
  269. package/lib/index-node-JVUj78ag.js.map +0 -1
package/lib/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "type": "git",
11
11
  "url": "https://github.com/AzureAD/microsoft-authentication-library-for-js.git"
12
12
  },
13
- "version": "16.11.3",
13
+ "version": "16.13.0",
14
14
  "description": "Microsoft Authentication Library for js",
15
15
  "keywords": [
16
16
  "implicit",
@@ -19,10 +19,7 @@ type RawMetadata = {
19
19
  // Build endpoint metadata dynamically to avoid string duplication
20
20
  const endpointHosts: Array<{ host: string; issuerHost?: string }> = [
21
21
  { host: "login.microsoftonline.com" },
22
- {
23
- host: "login.chinacloudapi.cn",
24
- issuerHost: "login.partner.microsoftonline.cn", // Issuer differs
25
- },
22
+ { host: "login.partner.microsoftonline.cn" },
26
23
  { host: "login.microsoftonline.us" },
27
24
  { host: "login.sovcloud-identity.fr" },
28
25
  { host: "login.sovcloud-identity.de" },
@@ -38,6 +38,7 @@ import { ServerTelemetryEntity } from "./entities/ServerTelemetryEntity.js";
38
38
  import { ThrottlingEntity } from "./entities/ThrottlingEntity.js";
39
39
  import { ICacheManager } from "./interface/ICacheManager.js";
40
40
  import * as AccountEntityUtils from "./utils/AccountEntityUtils.js";
41
+ import * as CacheHelpers from "./utils/CacheHelpers.js";
41
42
  import {
42
43
  AccountFilter,
43
44
  AppMetadataCache,
@@ -125,14 +126,17 @@ export abstract class CacheManager implements ICacheManager {
125
126
  ): AccessTokenEntity | null;
126
127
 
127
128
  /**
128
- * set accessToken entity to the platform cache
129
- * @param accessToken
130
- * @param correlationId
129
+ * Set accessToken entity to the platform cache
130
+ * @param accessToken - the access token entity to cache
131
+ * @param correlationId - unique identifier for the request
132
+ * @param kmsi - keep me signed in flag
133
+ * @param additionalCacheKeyHash - hash of additionalCacheKeyComponents for credential key generation
131
134
  */
132
135
  abstract setAccessTokenCredential(
133
136
  accessToken: AccessTokenEntity,
134
137
  correlationId: string,
135
- kmsi: boolean
138
+ kmsi: boolean,
139
+ additionalCacheKeyHash?: string
136
140
  ): Promise<void>;
137
141
 
138
142
  /**
@@ -268,8 +272,12 @@ export abstract class CacheManager implements ICacheManager {
268
272
  /**
269
273
  * Returns credential cache key from the entity
270
274
  * @param credential
275
+ * @param additionalCacheKeyHash - optional precomputed hash of additionalCacheKeyComponents
271
276
  */
272
- abstract generateCredentialKey(credential: CredentialEntity): string;
277
+ abstract generateCredentialKey(
278
+ credential: CredentialEntity,
279
+ additionalCacheKeyHash?: string
280
+ ): string;
273
281
 
274
282
  /**
275
283
  * Returns the account cache key from the account info
@@ -673,13 +681,25 @@ export abstract class CacheManager implements ICacheManager {
673
681
 
674
682
  /**
675
683
  * saves access token credential
676
- * @param credential
684
+ * @param credential - the access token entity to save
685
+ * @param correlationId - unique identifier for the request
686
+ * @param kmsi - keep me signed in flag
677
687
  */
678
688
  private async saveAccessToken(
679
689
  credential: AccessTokenEntity,
680
690
  correlationId: string,
681
691
  kmsi: boolean
682
692
  ): Promise<void> {
693
+ // Compute hash from components on the entity itself — no need to thread externally.
694
+ let additionalCacheKeyHash: string | undefined;
695
+ if (
696
+ credential.additionalCacheKeyComponents &&
697
+ Object.keys(credential.additionalCacheKeyComponents).length > 0
698
+ ) {
699
+ additionalCacheKeyHash = await this.cryptoImpl.hashString(
700
+ JSON.stringify(credential.additionalCacheKeyComponents)
701
+ );
702
+ }
683
703
  const accessTokenFilter: CredentialFilter = {
684
704
  clientId: credential.clientId,
685
705
  credentialType: credential.credentialType,
@@ -724,7 +744,12 @@ export abstract class CacheManager implements ICacheManager {
724
744
  }
725
745
  }
726
746
  });
727
- await this.setAccessTokenCredential(credential, correlationId, kmsi);
747
+ await this.setAccessTokenCredential(
748
+ credential,
749
+ correlationId,
750
+ kmsi,
751
+ additionalCacheKeyHash
752
+ );
728
753
  }
729
754
 
730
755
  /**
@@ -884,19 +909,9 @@ export abstract class CacheManager implements ICacheManager {
884
909
  entity.credentialType ===
885
910
  Constants.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME
886
911
  ) {
887
- if (
888
- !!filter.tokenType &&
889
- !this.matchTokenType(entity, filter.tokenType)
890
- ) {
912
+ if (!this.matchAccessTokenWithAuthScheme(entity, filter)) {
891
913
  return false;
892
914
  }
893
-
894
- // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
895
- if (filter.tokenType === Constants.AuthenticationScheme.SSH) {
896
- if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) {
897
- return false;
898
- }
899
- }
900
915
  }
901
916
 
902
917
  // Additional cache key components matching (bidirectional isolation)
@@ -1345,6 +1360,15 @@ export abstract class CacheManager implements ICacheManager {
1345
1360
  ? Constants.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME
1346
1361
  : Constants.CredentialType.ACCESS_TOKEN;
1347
1362
 
1363
+ const attributeTokenPartition = CacheHelpers.serializeAttributeTokens(
1364
+ request.attributeTokens
1365
+ );
1366
+ const additionalCacheKeyComponents = attributeTokenPartition
1367
+ ? {
1368
+ attribute_tokens: attributeTokenPartition,
1369
+ }
1370
+ : undefined;
1371
+
1348
1372
  const accessTokenFilter: CredentialFilter = {
1349
1373
  homeAccountId: account.homeAccountId,
1350
1374
  environment: account.environment,
@@ -1353,13 +1377,18 @@ export abstract class CacheManager implements ICacheManager {
1353
1377
  realm: targetRealm || account.tenantId,
1354
1378
  target: scopes,
1355
1379
  tokenType: authScheme,
1356
- keyId: request.sshKid,
1380
+ keyId:
1381
+ authScheme === Constants.AuthenticationScheme.SSH
1382
+ ? request.sshKid
1383
+ : undefined,
1384
+ additionalCacheKeyComponents: additionalCacheKeyComponents,
1357
1385
  };
1358
1386
 
1359
1387
  const accessTokenKeys =
1360
1388
  (tokenKeys && tokenKeys.accessToken) ||
1361
1389
  this.getTokenKeys().accessToken;
1362
1390
  const accessTokens: AccessTokenEntity[] = [];
1391
+ const matchedKeys: string[] = [];
1363
1392
 
1364
1393
  accessTokenKeys.forEach((key) => {
1365
1394
  // Validate key
@@ -1381,27 +1410,24 @@ export abstract class CacheManager implements ICacheManager {
1381
1410
  )
1382
1411
  ) {
1383
1412
  accessTokens.push(accessToken);
1413
+ matchedKeys.push(key);
1384
1414
  }
1385
1415
  }
1386
1416
  });
1387
1417
 
1388
- const numAccessTokens = accessTokens.length;
1389
- if (numAccessTokens < 1) {
1418
+ if (accessTokens.length < 1) {
1390
1419
  this.commonLogger.info(
1391
1420
  "CacheManager:getAccessToken - No token found",
1392
1421
  correlationId
1393
1422
  );
1394
1423
  return null;
1395
- } else if (numAccessTokens > 1) {
1424
+ } else if (accessTokens.length > 1) {
1396
1425
  this.commonLogger.info(
1397
1426
  "CacheManager:getAccessToken - Multiple access tokens found, clearing them",
1398
1427
  correlationId
1399
1428
  );
1400
- accessTokens.forEach((accessToken) => {
1401
- this.removeAccessToken(
1402
- this.generateCredentialKey(accessToken),
1403
- correlationId
1404
- );
1429
+ matchedKeys.forEach((key) => {
1430
+ this.removeAccessToken(key, correlationId);
1405
1431
  });
1406
1432
  this.performanceClient.addFields(
1407
1433
  { multiMatchedAT: accessTokens.length },
@@ -1937,7 +1963,47 @@ export abstract class CacheManager implements ICacheManager {
1937
1963
  entity: CredentialEntity,
1938
1964
  tokenType: Constants.AuthenticationScheme
1939
1965
  ): boolean {
1940
- return !!(entity.tokenType && entity.tokenType === tokenType);
1966
+ return !!(
1967
+ entity.tokenType &&
1968
+ entity.tokenType.toLowerCase() === tokenType.toLowerCase()
1969
+ );
1970
+ }
1971
+
1972
+ private matchAccessTokenWithAuthScheme(
1973
+ entity: CredentialEntity,
1974
+ filter: CredentialFilter
1975
+ ): boolean {
1976
+ const normalizedFilterTokenType = (
1977
+ filter.tokenType as string | undefined
1978
+ )?.toLowerCase();
1979
+
1980
+ if (
1981
+ !!filter.tokenType &&
1982
+ !this.matchTokenType(entity, filter.tokenType)
1983
+ ) {
1984
+ return false;
1985
+ }
1986
+
1987
+ switch (normalizedFilterTokenType) {
1988
+ case "dpop":
1989
+ return this.matchKeyBoundAccessToken(entity, filter, true);
1990
+ case Constants.AuthenticationScheme.SSH:
1991
+ return this.matchKeyBoundAccessToken(entity, filter, false);
1992
+ default:
1993
+ return true;
1994
+ }
1995
+ }
1996
+
1997
+ private matchKeyBoundAccessToken(
1998
+ entity: CredentialEntity,
1999
+ filter: CredentialFilter,
2000
+ requireKeyId: boolean
2001
+ ): boolean {
2002
+ if (!filter.keyId) {
2003
+ return !requireKeyId;
2004
+ }
2005
+
2006
+ return this.matchKeyId(entity, filter.keyId);
1941
2007
  }
1942
2008
 
1943
2009
  /**
@@ -2113,7 +2179,12 @@ export class DefaultStorageClass extends CacheManager {
2113
2179
  ""
2114
2180
  );
2115
2181
  }
2116
- generateCredentialKey(): string {
2182
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2183
+ generateCredentialKey(
2184
+ _credential: CredentialEntity,
2185
+ _hash?: string
2186
+ ): string {
2187
+ /* eslint-enable @typescript-eslint/no-unused-vars */
2117
2188
  throw createClientAuthError(
2118
2189
  ClientAuthErrorCodes.methodNotImplemented,
2119
2190
  ""
@@ -69,14 +69,17 @@ export interface ICacheManager {
69
69
  ): AccessTokenEntity | null;
70
70
 
71
71
  /**
72
- * set idToken entity to the platform cache
73
- * @param accessToken
74
- * @param correlationId
72
+ * set accessToken entity to the platform cache
73
+ * @param accessToken - the access token entity to cache
74
+ * @param correlationId - unique identifier for the request
75
+ * @param kmsi - keep me signed in flag
76
+ * @param additionalCacheKeyHash - optional precomputed hash of additionalCacheKeyComponents used in key generation
75
77
  */
76
78
  setAccessTokenCredential(
77
79
  accessToken: AccessTokenEntity,
78
80
  correlationId: string,
79
- kmsi: boolean
81
+ kmsi: boolean,
82
+ additionalCacheKeyHash?: string
80
83
  ): Promise<void>;
81
84
 
82
85
  /**
@@ -98,6 +98,7 @@ export function createAccessTokenEntity(
98
98
  atEntity.refreshOn = refreshOn.toString();
99
99
  }
100
100
 
101
+ const normalizedTokenType = atEntity.tokenType?.toLowerCase();
101
102
  /*
102
103
  * Create Access Token With Auth Scheme instead of regular access token
103
104
  * Cast to lower to handle "bearer" from ADFS
@@ -108,7 +109,7 @@ export function createAccessTokenEntity(
108
109
  ) {
109
110
  atEntity.credentialType =
110
111
  Constants.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
111
- switch (atEntity.tokenType) {
112
+ switch (normalizedTokenType) {
112
113
  case Constants.AuthenticationScheme.POP:
113
114
  // Make sure keyId is present and add it to credential
114
115
  const tokenClaims: TokenClaims | null = extractTokenClaims(
@@ -124,6 +125,15 @@ export function createAccessTokenEntity(
124
125
  }
125
126
  atEntity.keyId = tokenClaims.cnf.kid;
126
127
  break;
128
+ case "dpop":
129
+ if (!keyId) {
130
+ throw createClientAuthError(
131
+ ClientAuthErrorCodes.keyIdMissing,
132
+ correlationId
133
+ );
134
+ }
135
+ atEntity.keyId = keyId;
136
+ break;
127
137
  case Constants.AuthenticationScheme.SSH:
128
138
  atEntity.keyId = keyId;
129
139
  }
@@ -390,3 +400,20 @@ export function isAuthorityMetadataExpired(
390
400
  ): boolean {
391
401
  return metadata.expiresAt <= TimeUtils.nowSeconds();
392
402
  }
403
+
404
+ /**
405
+ * Serialize attribute tokens synchronously (sort and join).
406
+ * This is a sync-only operation for use at request construction time.
407
+ * @param attributeTokens - array of tokens
408
+ * @returns serialized partition string or undefined if no tokens
409
+ */
410
+ export function serializeAttributeTokens(
411
+ attributeTokens?: Array<string>
412
+ ): string | undefined {
413
+ if (!attributeTokens || attributeTokens.length === 0) {
414
+ return undefined;
415
+ }
416
+
417
+ // Serialize: sort and join tokens
418
+ return [...attributeTokens].sort().join(" ");
419
+ }
@@ -168,7 +168,8 @@ export class AuthorizationCodeClient {
168
168
  this.logger,
169
169
  this.performanceClient,
170
170
  this.config.serializableCache,
171
- this.config.persistencePlugin
171
+ this.config.persistencePlugin,
172
+ this.config.tokenBindingKeyManager
172
173
  );
173
174
 
174
175
  // Validate response. This function throws a server error if an error is returned by the server.
@@ -344,6 +345,19 @@ export class AuthorizationCodeClient {
344
345
 
345
346
  RequestParameterBuilder.addResource(parameters, request.resource);
346
347
 
348
+ if (request.attributeTokens) {
349
+ RequestParameterBuilder.addAttributeTokens(
350
+ parameters,
351
+ request.attributeTokens
352
+ );
353
+ }
354
+ this.performanceClient?.addFields(
355
+ {
356
+ hasAttributeTokens: !!request.attributeTokens?.length,
357
+ },
358
+ request.correlationId
359
+ );
360
+
347
361
  // add code: user set, not validated
348
362
  RequestParameterBuilder.addAuthorizationCode(parameters, request.code);
349
363
 
@@ -409,6 +423,7 @@ export class AuthorizationCodeClient {
409
423
  ) {
410
424
  const popTokenGenerator = new PopTokenGenerator(
411
425
  this.cryptoUtils,
426
+ this.config.tokenBindingKeyManager,
412
427
  this.performanceClient
413
428
  );
414
429
 
@@ -139,7 +139,8 @@ export class RefreshTokenClient {
139
139
  this.logger,
140
140
  this.performanceClient,
141
141
  this.config.serializableCache,
142
- this.config.persistencePlugin
142
+ this.config.persistencePlugin,
143
+ this.config.tokenBindingKeyManager
143
144
  );
144
145
  responseHandler.validateTokenResponse(
145
146
  response.body,
@@ -445,6 +446,19 @@ export class RefreshTokenClient {
445
446
  request.refreshToken
446
447
  );
447
448
 
449
+ if (request.attributeTokens) {
450
+ RequestParameterBuilder.addAttributeTokens(
451
+ parameters,
452
+ request.attributeTokens
453
+ );
454
+ }
455
+ this.performanceClient?.addFields(
456
+ {
457
+ hasAttributeTokens: !!request.attributeTokens?.length,
458
+ },
459
+ request.correlationId
460
+ );
461
+
448
462
  if (this.config.clientCredentials.clientSecret) {
449
463
  RequestParameterBuilder.addClientSecret(
450
464
  parameters,
@@ -475,6 +489,7 @@ export class RefreshTokenClient {
475
489
  ) {
476
490
  const popTokenGenerator = new PopTokenGenerator(
477
491
  this.cryptoUtils,
492
+ this.config.tokenBindingKeyManager,
478
493
  this.performanceClient
479
494
  );
480
495
 
@@ -263,7 +263,10 @@ export class SilentFlowClient {
263
263
  true,
264
264
  request,
265
265
  this.performanceClient,
266
- idTokenClaims
266
+ {
267
+ idTokenClaims,
268
+ tokenBindingKeyManager: this.config.tokenBindingKeyManager,
269
+ }
267
270
  );
268
271
  }
269
272
  }
@@ -5,6 +5,10 @@
5
5
 
6
6
  import { INetworkModule } from "../network/INetworkModule.js";
7
7
  import { DEFAULT_CRYPTO_IMPLEMENTATION, ICrypto } from "../crypto/ICrypto.js";
8
+ import {
9
+ DEFAULT_TOKEN_BINDING_KEY_MANAGER,
10
+ ITokenBindingKeyManager,
11
+ } from "../crypto/ITokenBindingKeyManager.js";
8
12
  import { ILoggerCallback, Logger, LogLevel } from "../logger/Logger.js";
9
13
  import {
10
14
  DEFAULT_COMMON_TENANT,
@@ -32,6 +36,7 @@ import { StubPerformanceClient } from "../telemetry/performance/StubPerformanceC
32
36
  * This object allows you to configure important elements of MSAL functionality:
33
37
  * - authOptions - Authentication for application
34
38
  * - cryptoInterface - Implementation of crypto functions
39
+ * - tokenBindingKeyManager - Implementation of token-binding key lifecycle functions
35
40
  * - libraryInfo - Library metadata
36
41
  * - telemetry - Telemetry options and data
37
42
  * - loggerOptions - Logging for application
@@ -48,6 +53,7 @@ export type ClientConfiguration = {
48
53
  storageInterface?: CacheManager;
49
54
  networkInterface?: INetworkModule;
50
55
  cryptoInterface?: ICrypto;
56
+ tokenBindingKeyManager?: ITokenBindingKeyManager;
51
57
  clientCredentials?: ClientCredentials;
52
58
  libraryInfo?: LibraryInfo;
53
59
  telemetry?: TelemetryOptions;
@@ -66,6 +72,7 @@ export type CommonClientConfiguration = {
66
72
  storageInterface: CacheManager;
67
73
  networkInterface: INetworkModule;
68
74
  cryptoInterface: Required<ICrypto>;
75
+ tokenBindingKeyManager: ITokenBindingKeyManager;
69
76
  libraryInfo: LibraryInfo;
70
77
  telemetry: Required<TelemetryOptions>;
71
78
  serverTelemetryManager: ServerTelemetryManager | null;
@@ -226,6 +233,7 @@ export function buildClientConfiguration({
226
233
  storageInterface: storageImplementation,
227
234
  networkInterface: networkImplementation,
228
235
  cryptoInterface: cryptoImplementation,
236
+ tokenBindingKeyManager: tokenBindingKeyManager,
229
237
  clientCredentials: clientCredentials,
230
238
  libraryInfo: libraryInfo,
231
239
  telemetry: telemetry,
@@ -253,6 +261,8 @@ export function buildClientConfiguration({
253
261
  networkInterface:
254
262
  networkImplementation || DEFAULT_NETWORK_IMPLEMENTATION,
255
263
  cryptoInterface: cryptoImplementation || DEFAULT_CRYPTO_IMPLEMENTATION,
264
+ tokenBindingKeyManager:
265
+ tokenBindingKeyManager || DEFAULT_TOKEN_BINDING_KEY_MANAGER,
256
266
  clientCredentials: clientCredentials || DEFAULT_CLIENT_CREDENTIALS,
257
267
  libraryInfo: { ...DEFAULT_LIBRARY_INFO, ...libraryInfo },
258
268
  telemetry: { ...DEFAULT_TELEMETRY_OPTIONS, ...telemetry },
@@ -68,3 +68,4 @@ export const USER_FEDERATED_IDENTITY_CREDENTIAL =
68
68
  export const USERNAME = "username";
69
69
  export const USER_ID = "user_id";
70
70
  export const FMI_PATH = "fmi_path";
71
+ export const ATTRIBUTE_TOKENS = "attribute_tokens";
@@ -4,11 +4,13 @@
4
4
  */
5
5
 
6
6
  import { ICrypto, JsonWebTokenAlgorithms } from "./ICrypto.js";
7
+ import { ITokenBindingKeyManager } from "./ITokenBindingKeyManager.js";
7
8
  import * as TimeUtils from "../utils/TimeUtils.js";
8
9
  import {
9
10
  createClientConfigurationError,
10
11
  ClientConfigurationErrorCodes,
11
12
  } from "../error/ClientConfigurationError.js";
13
+ import { JoseHeader } from "./JoseHeader.js";
12
14
 
13
15
  /**
14
16
  * RFC 9449 DPoP proof JWT payload claims.
@@ -44,51 +46,21 @@ export type DpopResourceProofParams = {
44
46
  nonce?: string;
45
47
  };
46
48
 
47
- /**
48
- * Public JWK embedded in the DPoP proof header.
49
- * @internal
50
- */
51
- export type DpopPublicJwk = Record<string, unknown>;
52
-
53
- /**
54
- * RFC 9449 DPoP proof JWT header.
55
- * @internal
56
- */
57
- export type DpopProofHeader = {
58
- typ: typeof DPOP_JWT_HEADER_TYPE;
59
- alg: string;
60
- jwk: DpopPublicJwk;
61
- };
62
-
63
- /**
64
- * Signs the ASCII DPoP JWT signing input with the declared JOSE alg
65
- * and returns a base64url-encoded signature.
66
- * @internal
67
- */
68
- export type DpopProofSigner = {
69
- alg: string;
70
- sign: (signingInput: string, correlationId: string) => Promise<string>;
71
- };
72
-
73
- /**
74
- * Parameters shared by token and resource DPoP proof generation.
75
- * @internal
76
- */
77
- export type DpopProofGenerationParams = {
78
- publicJwk: DpopPublicJwk;
79
- signer: DpopProofSigner;
80
- };
81
-
82
49
  const DPOP_HTM_REGEX = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
83
- export const DPOP_JWT_HEADER_TYPE = "dpop+jwt";
84
- export const DPOP_JWT_HEADER_ALGORITHM = JsonWebTokenAlgorithms.ES256;
85
-
86
- function buildProofHeader(params: DpopProofGenerationParams): DpopProofHeader {
87
- return {
88
- typ: DPOP_JWT_HEADER_TYPE,
89
- alg: params.signer.alg,
90
- jwk: params.publicJwk,
91
- };
50
+ const DPOP_TOKEN_BINDING_KEY_TYPE = "dpop";
51
+ const DPOP_JWT_HEADER_ALGORITHM = JsonWebTokenAlgorithms.ES256;
52
+
53
+ function buildProofHeader(
54
+ publicJwk: JsonWebKey,
55
+ correlationId: string
56
+ ): JoseHeader {
57
+ return JoseHeader.getDpopHeader(
58
+ {
59
+ alg: DPOP_JWT_HEADER_ALGORITHM,
60
+ jwk: publicJwk,
61
+ },
62
+ correlationId
63
+ );
92
64
  }
93
65
 
94
66
  function normalizeHtm(htm: string, correlationId: string): string {
@@ -149,9 +121,26 @@ function normalizeHtu(url: string, correlationId: string): string {
149
121
  */
150
122
  export class DpopProofGenerator {
151
123
  private cryptoUtils: ICrypto;
124
+ private tokenBindingKeyManager: ITokenBindingKeyManager;
152
125
 
153
- constructor(cryptoUtils: ICrypto) {
126
+ constructor(
127
+ cryptoUtils: ICrypto,
128
+ tokenBindingKeyManager: ITokenBindingKeyManager
129
+ ) {
154
130
  this.cryptoUtils = cryptoUtils;
131
+ this.tokenBindingKeyManager = tokenBindingKeyManager;
132
+ }
133
+
134
+ /**
135
+ * Provisions a fresh DPoP key and returns the RFC 7638 JWK thumbprint used
136
+ * as `dpop_jkt`.
137
+ */
138
+ async generateJkt(correlationId: string = ""): Promise<string> {
139
+ return this.tokenBindingKeyManager.provisionTokenBindingKey({
140
+ tokenBindingKeyType: DPOP_TOKEN_BINDING_KEY_TYPE,
141
+ tokenBindingKeyAlgorithm: DPOP_JWT_HEADER_ALGORITHM,
142
+ correlationId,
143
+ });
155
144
  }
156
145
 
157
146
  /**
@@ -180,12 +169,13 @@ export class DpopProofGenerator {
180
169
  * Builds and signs a compact DPoP proof JWT for a token-endpoint request.
181
170
  */
182
171
  async generateTokenProof(
183
- params: DpopTokenProofParams & DpopProofGenerationParams,
172
+ params: DpopTokenProofParams,
173
+ keyId: string,
184
174
  correlationId: string = ""
185
175
  ): Promise<string> {
186
176
  return this.generateProof(
187
177
  this.buildTokenProofClaims(params, correlationId),
188
- params,
178
+ keyId,
189
179
  correlationId
190
180
  );
191
181
  }
@@ -218,30 +208,33 @@ export class DpopProofGenerator {
218
208
  * Builds and signs a compact DPoP proof JWT for a resource request.
219
209
  */
220
210
  async generateResourceProof(
221
- params: DpopResourceProofParams & DpopProofGenerationParams,
211
+ params: DpopResourceProofParams,
212
+ keyId: string,
222
213
  correlationId: string = ""
223
214
  ): Promise<string> {
224
215
  return this.generateProof(
225
216
  this.buildResourceProofClaims(params, correlationId),
226
- params,
217
+ keyId,
227
218
  correlationId
228
219
  );
229
220
  }
230
221
 
231
222
  private async generateProof(
232
223
  claims: DpopProofClaims,
233
- params: DpopProofGenerationParams,
224
+ keyId: string,
234
225
  correlationId: string
235
226
  ): Promise<string> {
236
- const encodedHeader = this.cryptoUtils.base64UrlEncode(
237
- JSON.stringify(buildProofHeader(params))
238
- );
239
- const encodedClaims = this.cryptoUtils.base64UrlEncode(
240
- JSON.stringify(claims)
227
+ const publicJwk =
228
+ await this.tokenBindingKeyManager.getTokenBindingPublicKeyJwk(
229
+ keyId,
230
+ correlationId
231
+ );
232
+
233
+ return this.cryptoUtils.signTokenBindingJwt(
234
+ buildProofHeader(publicJwk, correlationId),
235
+ claims,
236
+ keyId,
237
+ correlationId
241
238
  );
242
- const signingInput = `${encodedHeader}.${encodedClaims}`;
243
- const signature = await params.signer.sign(signingInput, correlationId);
244
-
245
- return `${signingInput}.${signature}`;
246
239
  }
247
240
  }