UNPKG

botframework-connector

Version:

Bot Connector is autorest generated connector client.

116 lines 7.46 kB
"use strict"; /** * @module botframework-connector */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChannelValidation = void 0; const authenticationConstants_1 = require("./authenticationConstants"); const authenticationConfiguration_1 = require("./authenticationConfiguration"); const jwtTokenExtractor_1 = require("./jwtTokenExtractor"); const authenticationError_1 = require("./authenticationError"); const botframework_schema_1 = require("botframework-schema"); /** * @deprecated Use `ConfigurationBotFrameworkAuthentication` instead to perform channel validation. */ // eslint-disable-next-line @typescript-eslint/no-namespace var ChannelValidation; (function (ChannelValidation) { /** * TO BOT FROM CHANNEL: Token validation parameters when connecting to a bot */ ChannelValidation.ToBotFromChannelTokenValidationParameters = { issuer: [authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer], audience: undefined, clockTolerance: 5 * 60, ignoreExpiration: false, }; /** * Validate the incoming Auth Header as a token sent from the Bot Framework Service. * A token issued by the Bot Framework emulator will FAIL this check. * * @param {string} authHeader The raw HTTP header in the format: "Bearer [longString]" * @param {ICredentialProvider} credentials The user defined set of valid credentials, such as the AppId. * @param {string} serviceUrl The ServiceUrl Claim value that must match in the identity. * @param {string} channelId The ID of the channel to validate. * @param {AuthenticationConfiguration} authConfig The authentication configuration. * @returns {Promise<ClaimsIdentity>} A valid ClaimsIdentity. */ function authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { return __awaiter(this, void 0, void 0, function* () { const identity = yield authenticateChannelToken(authHeader, credentials, channelId, authConfig); const serviceUrlClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.ServiceUrlClaim); if (serviceUrlClaim !== serviceUrl) { // Claim must match. Not Authorized. throw new authenticationError_1.AuthenticationError('Unauthorized. ServiceUrl claim do not match.', botframework_schema_1.StatusCodes.UNAUTHORIZED); } return identity; }); } ChannelValidation.authenticateChannelTokenWithServiceUrl = authenticateChannelTokenWithServiceUrl; /** * Validate the incoming Auth Header as a token sent from the Bot Framework Service. * A token issued by the Bot Framework emulator will FAIL this check. * * @param {string} authHeader The raw HTTP header in the format: "Bearer [longString]" * @param {ICredentialProvider} credentials The user defined set of valid credentials, such as the AppId. * @param {string} channelId The ID of the channel to validate. * @param {AuthenticationConfiguration} authConfig The authentication configuration. * @returns {Promise<ClaimsIdentity>} A valid ClaimsIdentity. */ function authenticateChannelToken(authHeader, credentials, channelId, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { return __awaiter(this, void 0, void 0, function* () { const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(ChannelValidation.ToBotFromChannelTokenValidationParameters, ChannelValidation.OpenIdMetadataEndpoint ? ChannelValidation.OpenIdMetadataEndpoint : authenticationConstants_1.AuthenticationConstants.ToBotFromChannelOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, authConfig.requiredEndorsements); return yield validateIdentity(identity, credentials); }); } ChannelValidation.authenticateChannelToken = authenticateChannelToken; /** * Validate the ClaimsIdentity to ensure it came from the channel service. * * @param {ClaimsIdentity} identity The identity to validate * @param {ICredentialProvider} credentials The user defined set of valid credentials, such as the AppId. * @returns {Promise<ClaimsIdentity>} A valid ClaimsIdentity. */ function validateIdentity(identity, credentials) { return __awaiter(this, void 0, void 0, function* () { if (!identity || !identity.isAuthenticated) { // The token is in some way invalid. Not Authorized. throw new authenticationError_1.AuthenticationError('Unauthorized. Is not authenticated', botframework_schema_1.StatusCodes.UNAUTHORIZED); } // Now check that the AppID in the claimset matches // what we're looking for. Note that in a multi-tenant bot, this value // comes from developer code that may be reaching out to a service, hence the // Async validation. // Look for the "aud" claim, but only if issued from the Bot Framework if (identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.IssuerClaim) !== authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer) { // The relevant Audiance Claim MUST be present. Not Authorized. throw new authenticationError_1.AuthenticationError('Unauthorized. Issuer Claim MUST be present.', botframework_schema_1.StatusCodes.UNAUTHORIZED); } // The AppId from the claim in the token must match the AppId specified by the developer. // In this case, the token is destined for the app, so we find the app ID in the audience claim. const audClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); if (!(yield credentials.isValidAppId(audClaim || ''))) { // The AppId is not valid or not present. Not Authorized. throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${audClaim}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); } return identity; }); } ChannelValidation.validateIdentity = validateIdentity; })(ChannelValidation = exports.ChannelValidation || (exports.ChannelValidation = {})); //# sourceMappingURL=channelValidation.js.map