@azure/msal-common 16.12.0 → 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 (245) 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 +28 -11
  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 +10 -3
  22. package/dist/cache/utils/CacheHelpers.mjs.map +1 -1
  23. package/dist/client/AuthorizationCodeClient.mjs +3 -3
  24. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  25. package/dist/client/RefreshTokenClient.mjs +3 -3
  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 +1 -1
  32. package/dist/crypto/ICrypto.mjs +16 -11
  33. package/dist/crypto/ICrypto.mjs.map +1 -1
  34. package/dist/crypto/ITokenBindingKeyManager.mjs +28 -0
  35. package/dist/crypto/ITokenBindingKeyManager.mjs.map +1 -0
  36. package/dist/crypto/JoseHeader.mjs +38 -11
  37. package/dist/crypto/JoseHeader.mjs.map +1 -1
  38. package/dist/crypto/PopTokenGenerator.mjs +28 -5
  39. package/dist/crypto/PopTokenGenerator.mjs.map +1 -1
  40. package/dist/error/AuthError.mjs +1 -1
  41. package/dist/error/AuthErrorCodes.mjs +1 -1
  42. package/dist/error/CacheError.mjs +1 -1
  43. package/dist/error/CacheErrorCodes.mjs +1 -1
  44. package/dist/error/ClientAuthError.mjs +1 -1
  45. package/dist/error/ClientAuthErrorCodes.mjs +1 -1
  46. package/dist/error/ClientConfigurationError.mjs +1 -1
  47. package/dist/error/ClientConfigurationErrorCodes.mjs +3 -2
  48. package/dist/error/ClientConfigurationErrorCodes.mjs.map +1 -1
  49. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  50. package/dist/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
  51. package/dist/error/JoseHeaderError.mjs +1 -1
  52. package/dist/error/JoseHeaderErrorCodes.mjs +5 -3
  53. package/dist/error/JoseHeaderErrorCodes.mjs.map +1 -1
  54. package/dist/error/NetworkError.mjs +1 -1
  55. package/dist/error/PlatformBrokerError.mjs +1 -1
  56. package/dist/error/ServerError.mjs +1 -1
  57. package/dist/index-node.mjs +3 -2
  58. package/dist/index-node.mjs.map +1 -1
  59. package/dist/index.mjs +3 -2
  60. package/dist/index.mjs.map +1 -1
  61. package/dist/logger/Logger.mjs +1 -1
  62. package/dist/network/INetworkModule.mjs +1 -1
  63. package/dist/network/RequestThumbprint.mjs +1 -1
  64. package/dist/network/ThrottlingUtils.mjs +1 -1
  65. package/dist/packageMetadata.mjs +2 -2
  66. package/dist/protocol/Authorize.mjs +1 -1
  67. package/dist/protocol/Token.mjs +1 -1
  68. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  69. package/dist/request/BaseAuthRequest.mjs +1 -1
  70. package/dist/request/RequestParameterBuilder.mjs +1 -1
  71. package/dist/request/ScopeSet.mjs +1 -1
  72. package/dist/response/ResponseHandler.mjs +20 -6
  73. package/dist/response/ResponseHandler.mjs.map +1 -1
  74. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  75. package/dist/telemetry/performance/PerformanceEvent.mjs +1 -1
  76. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  77. package/dist/telemetry/performance/PerformanceEvents.mjs +1 -1
  78. package/dist/telemetry/performance/StubPerformanceClient.mjs +1 -1
  79. package/dist/telemetry/server/ServerTelemetryManager.mjs +1 -1
  80. package/dist/url/UrlString.mjs +1 -1
  81. package/dist/utils/ClientAssertionUtils.mjs +1 -1
  82. package/dist/utils/Constants.mjs +2 -1
  83. package/dist/utils/Constants.mjs.map +1 -1
  84. package/dist/utils/FunctionWrappers.mjs +1 -1
  85. package/dist/utils/ObjectUtils.mjs +28 -0
  86. package/dist/utils/ObjectUtils.mjs.map +1 -0
  87. package/dist/utils/ProtocolUtils.mjs +1 -1
  88. package/dist/utils/StringUtils.mjs +1 -1
  89. package/dist/utils/TimeUtils.mjs +1 -1
  90. package/dist/utils/UrlUtils.mjs +1 -1
  91. package/dist-browser/account/AccountInfo.mjs +1 -1
  92. package/dist-browser/account/AuthToken.mjs +1 -1
  93. package/dist-browser/account/CcsCredential.mjs +1 -1
  94. package/dist-browser/account/ClientInfo.mjs +1 -1
  95. package/dist-browser/account/TokenClaims.mjs +1 -1
  96. package/dist-browser/authority/Authority.mjs +1 -1
  97. package/dist-browser/authority/AuthorityFactory.mjs +1 -1
  98. package/dist-browser/authority/AuthorityMetadata.mjs +2 -5
  99. package/dist-browser/authority/AuthorityMetadata.mjs.map +1 -1
  100. package/dist-browser/authority/AuthorityOptions.mjs +1 -1
  101. package/dist-browser/authority/AuthorityType.mjs +1 -1
  102. package/dist-browser/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  103. package/dist-browser/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  104. package/dist-browser/authority/OpenIdConfigResponse.mjs +1 -1
  105. package/dist-browser/authority/ProtocolMode.mjs +1 -1
  106. package/dist-browser/authority/RegionDiscovery.mjs +1 -1
  107. package/dist-browser/cache/CacheManager.mjs +28 -11
  108. package/dist-browser/cache/CacheManager.mjs.map +1 -1
  109. package/dist-browser/cache/persistence/TokenCacheContext.mjs +1 -1
  110. package/dist-browser/cache/utils/AccountEntityUtils.mjs +1 -1
  111. package/dist-browser/cache/utils/CacheHelpers.mjs +10 -3
  112. package/dist-browser/cache/utils/CacheHelpers.mjs.map +1 -1
  113. package/dist-browser/client/AuthorizationCodeClient.mjs +3 -3
  114. package/dist-browser/client/AuthorizationCodeClient.mjs.map +1 -1
  115. package/dist-browser/client/RefreshTokenClient.mjs +3 -3
  116. package/dist-browser/client/RefreshTokenClient.mjs.map +1 -1
  117. package/dist-browser/client/SilentFlowClient.mjs +5 -2
  118. package/dist-browser/client/SilentFlowClient.mjs.map +1 -1
  119. package/dist-browser/config/ClientConfiguration.mjs +4 -2
  120. package/dist-browser/config/ClientConfiguration.mjs.map +1 -1
  121. package/dist-browser/constants/AADServerParamKeys.mjs +1 -1
  122. package/dist-browser/crypto/ICrypto.mjs +16 -11
  123. package/dist-browser/crypto/ICrypto.mjs.map +1 -1
  124. package/dist-browser/crypto/ITokenBindingKeyManager.mjs +28 -0
  125. package/dist-browser/crypto/ITokenBindingKeyManager.mjs.map +1 -0
  126. package/dist-browser/crypto/JoseHeader.mjs +38 -11
  127. package/dist-browser/crypto/JoseHeader.mjs.map +1 -1
  128. package/dist-browser/crypto/PopTokenGenerator.mjs +28 -5
  129. package/dist-browser/crypto/PopTokenGenerator.mjs.map +1 -1
  130. package/dist-browser/error/AuthError.mjs +1 -1
  131. package/dist-browser/error/AuthErrorCodes.mjs +1 -1
  132. package/dist-browser/error/CacheError.mjs +1 -1
  133. package/dist-browser/error/CacheErrorCodes.mjs +1 -1
  134. package/dist-browser/error/ClientAuthError.mjs +1 -1
  135. package/dist-browser/error/ClientAuthErrorCodes.mjs +1 -1
  136. package/dist-browser/error/ClientConfigurationError.mjs +1 -1
  137. package/dist-browser/error/ClientConfigurationErrorCodes.mjs +3 -2
  138. package/dist-browser/error/ClientConfigurationErrorCodes.mjs.map +1 -1
  139. package/dist-browser/error/InteractionRequiredAuthError.mjs +1 -1
  140. package/dist-browser/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
  141. package/dist-browser/error/JoseHeaderError.mjs +1 -1
  142. package/dist-browser/error/JoseHeaderErrorCodes.mjs +5 -3
  143. package/dist-browser/error/JoseHeaderErrorCodes.mjs.map +1 -1
  144. package/dist-browser/error/NetworkError.mjs +1 -1
  145. package/dist-browser/error/PlatformBrokerError.mjs +1 -1
  146. package/dist-browser/error/ServerError.mjs +1 -1
  147. package/dist-browser/index-browser.mjs +3 -2
  148. package/dist-browser/index-browser.mjs.map +1 -1
  149. package/dist-browser/index.mjs +3 -2
  150. package/dist-browser/index.mjs.map +1 -1
  151. package/dist-browser/log-strings-mapping.json +2 -2
  152. package/dist-browser/logger/Logger.mjs +1 -1
  153. package/dist-browser/network/INetworkModule.mjs +1 -1
  154. package/dist-browser/network/RequestThumbprint.mjs +1 -1
  155. package/dist-browser/network/ThrottlingUtils.mjs +1 -1
  156. package/dist-browser/packageMetadata.mjs +2 -2
  157. package/dist-browser/protocol/Authorize.mjs +1 -1
  158. package/dist-browser/protocol/Token.mjs +1 -1
  159. package/dist-browser/request/AuthenticationHeaderParser.mjs +1 -1
  160. package/dist-browser/request/BaseAuthRequest.mjs +1 -1
  161. package/dist-browser/request/RequestParameterBuilder.mjs +1 -1
  162. package/dist-browser/request/ScopeSet.mjs +1 -1
  163. package/dist-browser/response/ResponseHandler.mjs +20 -6
  164. package/dist-browser/response/ResponseHandler.mjs.map +1 -1
  165. package/dist-browser/telemetry/performance/PerformanceClient.mjs +1 -1
  166. package/dist-browser/telemetry/performance/PerformanceEvent.mjs +1 -1
  167. package/dist-browser/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  168. package/dist-browser/telemetry/performance/PerformanceEvents.mjs +1 -1
  169. package/dist-browser/telemetry/performance/StubPerformanceClient.mjs +1 -1
  170. package/dist-browser/telemetry/server/ServerTelemetryManager.mjs +1 -1
  171. package/dist-browser/url/UrlString.mjs +1 -1
  172. package/dist-browser/utils/ClientAssertionUtils.mjs +1 -1
  173. package/dist-browser/utils/Constants.mjs +2 -1
  174. package/dist-browser/utils/Constants.mjs.map +1 -1
  175. package/dist-browser/utils/FunctionWrappers.mjs +1 -1
  176. package/dist-browser/utils/ObjectUtils.mjs +28 -0
  177. package/dist-browser/utils/ObjectUtils.mjs.map +1 -0
  178. package/dist-browser/utils/ProtocolUtils.mjs +1 -1
  179. package/dist-browser/utils/StringUtils.mjs +1 -1
  180. package/dist-browser/utils/TimeUtils.mjs +1 -1
  181. package/dist-browser/utils/UrlUtils.mjs +1 -1
  182. package/lib/index-browser.cjs +5 -67
  183. package/lib/index-browser.cjs.map +1 -1
  184. package/lib/{index-node-3p7V__ym.js → index-node-BaODPZEy.js} +252 -46
  185. package/lib/index-node-BaODPZEy.js.map +1 -0
  186. package/lib/index-node.cjs +4 -2
  187. package/lib/index-node.cjs.map +1 -1
  188. package/lib/index.cjs +5 -3
  189. package/lib/index.cjs.map +1 -1
  190. package/package.json +1 -1
  191. package/src/authority/AuthorityMetadata.ts +1 -4
  192. package/src/cache/CacheManager.ts +46 -13
  193. package/src/cache/utils/CacheHelpers.ts +11 -1
  194. package/src/client/AuthorizationCodeClient.ts +3 -1
  195. package/src/client/RefreshTokenClient.ts +3 -1
  196. package/src/client/SilentFlowClient.ts +4 -1
  197. package/src/config/ClientConfiguration.ts +10 -0
  198. package/src/crypto/DpopProofGenerator.ts +52 -59
  199. package/src/crypto/ICrypto.ts +31 -26
  200. package/src/crypto/ITokenBindingKeyManager.ts +84 -0
  201. package/src/crypto/JoseHeader.ts +74 -14
  202. package/src/crypto/PopTokenGenerator.ts +62 -18
  203. package/src/error/ClientConfigurationErrorCodes.ts +2 -0
  204. package/src/error/JoseHeaderErrorCodes.ts +2 -0
  205. package/src/exports-common.ts +7 -0
  206. package/src/packageMetadata.ts +1 -1
  207. package/src/response/ResponseHandler.ts +43 -14
  208. package/src/telemetry/performance/PerformanceEvent.ts +10 -0
  209. package/src/utils/Constants.ts +1 -0
  210. package/src/utils/ObjectUtils.ts +31 -0
  211. package/types/authority/AuthorityMetadata.d.ts.map +1 -1
  212. package/types/cache/CacheManager.d.ts +2 -0
  213. package/types/cache/CacheManager.d.ts.map +1 -1
  214. package/types/cache/utils/CacheHelpers.d.ts.map +1 -1
  215. package/types/client/AuthorizationCodeClient.d.ts.map +1 -1
  216. package/types/client/RefreshTokenClient.d.ts.map +1 -1
  217. package/types/client/SilentFlowClient.d.ts.map +1 -1
  218. package/types/config/ClientConfiguration.d.ts +5 -1
  219. package/types/config/ClientConfiguration.d.ts.map +1 -1
  220. package/types/crypto/DpopProofGenerator.d.ts +10 -36
  221. package/types/crypto/DpopProofGenerator.d.ts.map +1 -1
  222. package/types/crypto/ICrypto.d.ts +10 -9
  223. package/types/crypto/ICrypto.d.ts.map +1 -1
  224. package/types/crypto/ITokenBindingKeyManager.d.ts +41 -0
  225. package/types/crypto/ITokenBindingKeyManager.d.ts.map +1 -0
  226. package/types/crypto/JoseHeader.d.ts +17 -5
  227. package/types/crypto/JoseHeader.d.ts.map +1 -1
  228. package/types/crypto/PopTokenGenerator.d.ts +3 -1
  229. package/types/crypto/PopTokenGenerator.d.ts.map +1 -1
  230. package/types/error/ClientConfigurationErrorCodes.d.ts +1 -0
  231. package/types/error/ClientConfigurationErrorCodes.d.ts.map +1 -1
  232. package/types/error/JoseHeaderErrorCodes.d.ts +2 -0
  233. package/types/error/JoseHeaderErrorCodes.d.ts.map +1 -1
  234. package/types/exports-common.d.ts +3 -2
  235. package/types/exports-common.d.ts.map +1 -1
  236. package/types/packageMetadata.d.ts +1 -1
  237. package/types/response/ResponseHandler.d.ts +12 -2
  238. package/types/response/ResponseHandler.d.ts.map +1 -1
  239. package/types/telemetry/performance/PerformanceEvent.d.ts +8 -0
  240. package/types/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  241. package/types/utils/Constants.d.ts +1 -0
  242. package/types/utils/Constants.d.ts.map +1 -1
  243. package/types/utils/ObjectUtils.d.ts +6 -0
  244. package/types/utils/ObjectUtils.d.ts.map +1 -0
  245. package/lib/index-node-3p7V__ym.js.map +0 -1
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.12.0",
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" },
@@ -909,19 +909,9 @@ export abstract class CacheManager implements ICacheManager {
909
909
  entity.credentialType ===
910
910
  Constants.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME
911
911
  ) {
912
- if (
913
- !!filter.tokenType &&
914
- !this.matchTokenType(entity, filter.tokenType)
915
- ) {
912
+ if (!this.matchAccessTokenWithAuthScheme(entity, filter)) {
916
913
  return false;
917
914
  }
918
-
919
- // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
920
- if (filter.tokenType === Constants.AuthenticationScheme.SSH) {
921
- if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) {
922
- return false;
923
- }
924
- }
925
915
  }
926
916
 
927
917
  // Additional cache key components matching (bidirectional isolation)
@@ -1387,7 +1377,10 @@ export abstract class CacheManager implements ICacheManager {
1387
1377
  realm: targetRealm || account.tenantId,
1388
1378
  target: scopes,
1389
1379
  tokenType: authScheme,
1390
- keyId: request.sshKid,
1380
+ keyId:
1381
+ authScheme === Constants.AuthenticationScheme.SSH
1382
+ ? request.sshKid
1383
+ : undefined,
1391
1384
  additionalCacheKeyComponents: additionalCacheKeyComponents,
1392
1385
  };
1393
1386
 
@@ -1970,7 +1963,47 @@ export abstract class CacheManager implements ICacheManager {
1970
1963
  entity: CredentialEntity,
1971
1964
  tokenType: Constants.AuthenticationScheme
1972
1965
  ): boolean {
1973
- 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);
1974
2007
  }
1975
2008
 
1976
2009
  /**
@@ -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
  }
@@ -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.
@@ -422,6 +423,7 @@ export class AuthorizationCodeClient {
422
423
  ) {
423
424
  const popTokenGenerator = new PopTokenGenerator(
424
425
  this.cryptoUtils,
426
+ this.config.tokenBindingKeyManager,
425
427
  this.performanceClient
426
428
  );
427
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,
@@ -488,6 +489,7 @@ export class RefreshTokenClient {
488
489
  ) {
489
490
  const popTokenGenerator = new PopTokenGenerator(
490
491
  this.cryptoUtils,
492
+ this.config.tokenBindingKeyManager,
491
493
  this.performanceClient
492
494
  );
493
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 },
@@ -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
  }
@@ -8,7 +8,7 @@ import {
8
8
  createClientAuthError,
9
9
  } from "../error/ClientAuthError.js";
10
10
  import type { BaseAuthRequest } from "../request/BaseAuthRequest.js";
11
- import type { ShrOptions, SignedHttpRequest } from "./SignedHttpRequest.js";
11
+ import type { JoseHeader } from "./JoseHeader.js";
12
12
 
13
13
  /**
14
14
  * PKCE code verifier and challenge pair used by authorization code flows.
@@ -35,9 +35,11 @@ export type SignedHttpRequestParameters = Pick<
35
35
 
36
36
  /**
37
37
  * Shared JOSE algorithm literals used by MSAL package internals.
38
+ * @internal
38
39
  */
39
40
  export const JsonWebTokenAlgorithms = {
40
41
  ES256: "ES256",
42
+ RS256: "RS256",
41
43
  } as const;
42
44
  /**
43
45
  * Interface for crypto functions used by library
@@ -67,13 +69,6 @@ export interface ICrypto {
67
69
  * @returns Base64Url encoded public key
68
70
  */
69
71
  encodeKid(inputKid: string): string;
70
- /**
71
- * Generates an JWK RSA S256 Thumbprint
72
- * @param request
73
- */
74
- getPublicKeyThumbprint(
75
- request: SignedHttpRequestParameters
76
- ): Promise<string>;
77
72
  /**
78
73
  * Removes cryptographic keypair from key store matching the keyId passed in
79
74
  * @param kid
@@ -86,14 +81,18 @@ export interface ICrypto {
86
81
  */
87
82
  clearKeystore(correlationId: string): Promise<boolean>;
88
83
  /**
89
- * Returns a signed proof-of-possession token with a given acces token that contains a cnf claim with the required kid.
90
- * @param accessToken
84
+ * Signs a compact JWT with the token-binding key identified by kid.
85
+ * @internal
86
+ * @param header
87
+ * @param payload
88
+ * @param kid
89
+ * @param correlationId
91
90
  */
92
- signJwt(
93
- payload: SignedHttpRequest,
91
+ signTokenBindingJwt(
92
+ header: JoseHeader,
93
+ payload: object,
94
94
  kid: string,
95
- shrOptions?: ShrOptions,
96
- correlationId?: string
95
+ correlationId: string
97
96
  ): Promise<string>;
98
97
  /**
99
98
  * Returns the SHA-256 hash of an input string
@@ -137,28 +136,34 @@ export const DEFAULT_CRYPTO_IMPLEMENTATION: ICrypto = {
137
136
  ""
138
137
  );
139
138
  },
140
- async getPublicKeyThumbprint(): Promise<string> {
141
- throw createClientAuthError(
142
- ClientAuthErrorCodes.methodNotImplemented,
143
- ""
144
- );
145
- },
146
- async removeTokenBindingKey(): Promise<void> {
139
+ async removeTokenBindingKey(
140
+ kid: string,
141
+ correlationId: string
142
+ ): Promise<void> {
143
+ void kid;
147
144
  throw createClientAuthError(
148
145
  ClientAuthErrorCodes.methodNotImplemented,
149
- ""
146
+ correlationId
150
147
  );
151
148
  },
152
- async clearKeystore(): Promise<boolean> {
149
+ async clearKeystore(correlationId: string): Promise<boolean> {
153
150
  throw createClientAuthError(
154
151
  ClientAuthErrorCodes.methodNotImplemented,
155
- ""
152
+ correlationId
156
153
  );
157
154
  },
158
- async signJwt(): Promise<string> {
155
+ async signTokenBindingJwt(
156
+ header: JoseHeader,
157
+ payload: object,
158
+ kid: string,
159
+ correlationId: string
160
+ ): Promise<string> {
161
+ void header;
162
+ void payload;
163
+ void kid;
159
164
  throw createClientAuthError(
160
165
  ClientAuthErrorCodes.methodNotImplemented,
161
- ""
166
+ correlationId
162
167
  );
163
168
  },
164
169
  async hashString(): Promise<string> {
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ ClientAuthErrorCodes,
8
+ createClientAuthError,
9
+ } from "../error/ClientAuthError.js";
10
+
11
+ /**
12
+ * Parameters used by token-binding key managers to provision browser-managed
13
+ * token-binding keys. Callers own the protocol policy (key type and JOSE
14
+ * algorithm); implementations generate, store, retrieve, and use the requested
15
+ * key material by key identifier.
16
+ */
17
+ export type TokenBindingKeyProvisioningParameters = {
18
+ tokenBindingKeyType: string;
19
+ tokenBindingKeyAlgorithm: string;
20
+ correlationId: string;
21
+ };
22
+
23
+ /**
24
+ * Internal key lifecycle abstraction for browser token-binding keys.
25
+ * @internal
26
+ */
27
+ export interface ITokenBindingKeyManager {
28
+ /**
29
+ * Provisions a token-binding key and returns the key identifier.
30
+ * @param request - Key provisioning policy.
31
+ */
32
+ provisionTokenBindingKey(
33
+ request: TokenBindingKeyProvisioningParameters
34
+ ): Promise<string>;
35
+ /**
36
+ * Removes a token-binding key by identifier.
37
+ * @param kid - Token-binding key identifier.
38
+ * @param correlationId - Request correlation identifier.
39
+ */
40
+ removeTokenBindingKey(kid: string, correlationId: string): Promise<void>;
41
+ /**
42
+ * Gets a token-binding public key as a JWK by identifier.
43
+ * @param kid - Token-binding key identifier.
44
+ * @param correlationId - Request correlation identifier.
45
+ */
46
+ getTokenBindingPublicKeyJwk(
47
+ kid: string,
48
+ correlationId: string
49
+ ): Promise<JsonWebKey>;
50
+ }
51
+
52
+ /**
53
+ * Default token-binding key manager used when a platform-specific implementation
54
+ * has not been provided.
55
+ * @internal
56
+ */
57
+ export const DEFAULT_TOKEN_BINDING_KEY_MANAGER: ITokenBindingKeyManager = {
58
+ async provisionTokenBindingKey(
59
+ request: TokenBindingKeyProvisioningParameters
60
+ ): Promise<string> {
61
+ throw createClientAuthError(
62
+ ClientAuthErrorCodes.methodNotImplemented,
63
+ request.correlationId
64
+ );
65
+ },
66
+ async removeTokenBindingKey(
67
+ _kid: string,
68
+ correlationId: string
69
+ ): Promise<void> {
70
+ throw createClientAuthError(
71
+ ClientAuthErrorCodes.methodNotImplemented,
72
+ correlationId
73
+ );
74
+ },
75
+ async getTokenBindingPublicKeyJwk(
76
+ _kid: string,
77
+ correlationId: string
78
+ ): Promise<JsonWebKey> {
79
+ throw createClientAuthError(
80
+ ClientAuthErrorCodes.methodNotImplemented,
81
+ correlationId
82
+ );
83
+ },
84
+ };