msiTokenCredentials.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. "use strict";
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // Licensed under the MIT License. See License.txt in the project root for license information.
  4. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  5. return new (P || (P = Promise))(function (resolve, reject) {
  6. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  7. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  8. function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
  9. step((generator = generator.apply(thisArg, _arguments || [])).next());
  10. });
  11. };
  12. Object.defineProperty(exports, "__esModule", { value: true });
  13. const ms_rest_js_1 = require("@azure/ms-rest-js");
  14. const authConstants_1 = require("../util/authConstants");
  15. /**
  16. * @class MSITokenCredentials - Provides information about managed service identity token credentials.
  17. * This object can only be used to acquire token on a virtual machine provisioned in Azure with managed service identity.
  18. */
  19. class MSITokenCredentials {
  20. /**
  21. * Creates an instance of MSITokenCredentials.
  22. * @param {object} [options] - Optional parameters
  23. * @param {string} [options.resource] - The resource uri or token audience for which the token is needed.
  24. * For e.g. it can be:
  25. * - resource management endpoint "https://management.azure.com/"(default)
  26. * - management endpoint "https://management.core.windows.net/"
  27. */
  28. constructor(options) {
  29. if (!options)
  30. options = {};
  31. if (!options.resource) {
  32. options.resource = authConstants_1.AuthConstants.RESOURCE_MANAGER_ENDPOINT;
  33. }
  34. else if (typeof options.resource.valueOf() !== "string") {
  35. throw new Error("resource must be a uri.");
  36. }
  37. this.resource = options.resource;
  38. this._httpClient = options.httpClient || new ms_rest_js_1.DefaultHttpClient();
  39. }
  40. /**
  41. * Parses a tokenResponse json string into a object, and converts properties on the first level to camelCase.
  42. * This method tries to standardize the tokenResponse
  43. * @param {string} body A json string
  44. * @return {object} [tokenResponse] The tokenResponse (tokenType and accessToken are the two important properties).
  45. */
  46. parseTokenResponse(body) {
  47. // Docs show different examples of possible MSI responses for different services. https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview
  48. // expires_on - is a Date like string in this doc
  49. // - https://docs.microsoft.com/en-us/azure/app-service/app-service-managed-service-identity#rest-protocol-examples
  50. // In other doc it is stringified number.
  51. // - https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/tutorial-linux-vm-access-arm#get-an-access-token-using-the-vms-identity-and-use-it-to-call-resource-manager
  52. const parsedBody = JSON.parse(body);
  53. parsedBody.accessToken = parsedBody["access_token"];
  54. delete parsedBody["access_token"];
  55. parsedBody.tokenType = parsedBody["token_type"];
  56. delete parsedBody["token_type"];
  57. if (parsedBody["refresh_token"]) {
  58. parsedBody.refreshToken = parsedBody["refresh_token"];
  59. delete parsedBody["refresh_token"];
  60. }
  61. if (parsedBody["expires_in"]) {
  62. parsedBody.expiresIn = parsedBody["expires_in"];
  63. if (typeof parsedBody["expires_in"] === "string") {
  64. // normal number as a string '1504130527'
  65. parsedBody.expiresIn = parseInt(parsedBody["expires_in"], 10);
  66. }
  67. delete parsedBody["expires_in"];
  68. }
  69. if (parsedBody["not_before"]) {
  70. parsedBody.notBefore = parsedBody["not_before"];
  71. if (typeof parsedBody["not_before"] === "string") {
  72. // normal number as a string '1504130527'
  73. parsedBody.notBefore = parseInt(parsedBody["not_before"], 10);
  74. }
  75. delete parsedBody["not_before"];
  76. }
  77. if (parsedBody["expires_on"]) {
  78. parsedBody.expiresOn = parsedBody["expires_on"];
  79. if (typeof parsedBody["expires_on"] === "string") {
  80. // possibly a Date string '09/14/2017 00:00:00 PM +00:00'
  81. if (parsedBody["expires_on"].includes(":") || parsedBody["expires_on"].includes("/")) {
  82. parsedBody.expiresOn = new Date(parsedBody["expires_on"], 10);
  83. }
  84. else {
  85. // normal number as a string '1504130527'
  86. parsedBody.expiresOn = new Date(parseInt(parsedBody["expires_on"], 10));
  87. }
  88. }
  89. delete parsedBody["expires_on"];
  90. }
  91. return parsedBody;
  92. }
  93. /**
  94. * Signs a request with the Authentication header.
  95. *
  96. * @param {webResource} The WebResource to be signed.
  97. * @return {Promise<WebResource>} Promise with signed WebResource.
  98. */
  99. signRequest(webResource) {
  100. return __awaiter(this, void 0, void 0, function* () {
  101. const tokenResponse = yield this.getToken();
  102. webResource.headers.set(ms_rest_js_1.Constants.HeaderConstants.AUTHORIZATION, `${tokenResponse.tokenType} ${tokenResponse.accessToken}`);
  103. return Promise.resolve(webResource);
  104. });
  105. }
  106. }
  107. exports.MSITokenCredentials = MSITokenCredentials;
  108. //# sourceMappingURL=msiTokenCredentials.js.map