botframework-connector
Version:
Bot Connector is autorest generated connector client.
116 lines • 7.46 kB
JavaScript
;
/**
* @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