diff --git a/libraries/botframework-connector/src/auth/aseChannelValidation.ts b/libraries/botframework-connector/src/auth/aseChannelValidation.ts index a580b8189e..4d326e6279 100644 --- a/libraries/botframework-connector/src/auth/aseChannelValidation.ts +++ b/libraries/botframework-connector/src/auth/aseChannelValidation.ts @@ -25,40 +25,45 @@ import { BetweenBotAndAseChannelTokenValidationParameters } from './tokenValidat * Validates and Examines JWT tokens from the Bot Framework AseChannel */ export namespace AseChannelValidation { - const ChannelId = "AseChannel"; + const ChannelId = 'AseChannel'; let _creadentialProvider: ICredentialProvider; let _channelService: string; export let MetadataUrl: string; - export function init(configuration: any) - { - let appId = configuration.MicrosoftAppId; - let tenantId = configuration.MicrosoftAppTenantId; + /** + * init authentication from user .env configuration. + * + * @param configuration The user .env configuration. + */ + export function init(configuration: any) { + const appId = configuration.MicrosoftAppId; + const tenantId = configuration.MicrosoftAppTenantId; _channelService = configuration.ChannelService; - MetadataUrl = _channelService !== undefined && JwtTokenValidation.isGovernment(_channelService) - ? GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl - : AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl; + MetadataUrl = + _channelService !== undefined && JwtTokenValidation.isGovernment(_channelService) + ? GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl + : AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl; - _creadentialProvider = new SimpleCredentialProvider(appId, ""); + _creadentialProvider = new SimpleCredentialProvider(appId, ''); - let tenantIds: string[] = [ + const tenantIds: string[] = [ tenantId, - "f8cdef31-a31e-4b4a-93e4-5f571e91255a", // US Gov MicrosoftServices.onmicrosoft.us - "d6d49420-f39b-4df7-a1dc-d59a935871db" // Public botframework.com + 'f8cdef31-a31e-4b4a-93e4-5f571e91255a', // US Gov MicrosoftServices.onmicrosoft.us + 'd6d49420-f39b-4df7-a1dc-d59a935871db', // Public botframework.com ]; - let validIssuers: string[] = []; + const validIssuers: string[] = []; tenantIds.forEach((tmpId: string) => { validIssuers.push(`https://sts.windows.net/${tmpId}/`); // Auth Public/US Gov, 1.0 token validIssuers.push(`https://login.microsoftonline.com/${tmpId}/v2.0`); // Auth Public, 2.0 token validIssuers.push(`https://login.microsoftonline.us/${tmpId}/v2.0`); // Auth for US Gov, 2.0 token - }) + }); BetweenBotAndAseChannelTokenValidationParameters.issuer = validIssuers; } /** * Determines if a given Auth header is from the Bot Framework AseChannel * - * @param {string} channelId. + * @param {string} channelId The channelId. * @returns {boolean} True, if the token was issued by the AseChannel. Otherwise, false. */ export function isTokenFromAseChannel(channelId: string): boolean { @@ -69,17 +74,14 @@ export namespace AseChannelValidation { * Validate the incoming Auth Header as a token sent from the Bot Framework AseChannel. * A token issued by the Bot Framework will FAIL this check. Only AseChannel tokens will pass. * - * @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} channelService The channelService value that distinguishes public Azure from US Government Azure. - * @param {AuthenticationConfiguration} authConfig The authentication configuration. + * @param {string} authHeader The raw HTTP header in the format: 'Bearer [longString]' + * @param {AuthenticationConfiguration} authConfig The authentication configuration. * @returns {Promise} A valid ClaimsIdentity. */ export async function authenticateAseChannelToken( authHeader: string, authConfig: AuthenticationConfiguration = new AuthenticationConfiguration() ): Promise { - const tokenExtractor: JwtTokenExtractor = new JwtTokenExtractor( BetweenBotAndAseChannelTokenValidationParameters, MetadataUrl, @@ -108,14 +110,14 @@ export namespace AseChannelValidation { const versionClaim: string = identity.getClaimValue(AuthenticationConstants.VersionClaim); if (versionClaim === null) { throw new AuthenticationError( - 'Unauthorized. "ver" claim is required on AseChannel Tokens.', + 'Unauthorized. "ver" claim is required on Emulator Tokens.', StatusCodes.UNAUTHORIZED ); } let appId = ''; - // The AseChannel, depending on Version, sends the AppId via either the + // The Emulator, depending on Version, sends the AppId via either the // appid claim (Version 1) or the Authorized Party claim (Version 2). if (!versionClaim || versionClaim === '1.0') { // either no Version or a version of "1.0" means we should look for @@ -124,19 +126,19 @@ export namespace AseChannelValidation { if (!appIdClaim) { // No claim around AppID. Not Authorized. throw new AuthenticationError( - 'Unauthorized. "appid" claim is required on AseChannel Token version "1.0".', + 'Unauthorized. "appid" claim is required on Emulator Token version "1.0".', StatusCodes.UNAUTHORIZED ); } appId = appIdClaim; } else if (versionClaim === '2.0') { - // AseChannel, "2.0" puts the AppId in the "azp" claim. + // Emulator, "2.0" puts the AppId in the "azp" claim. const appZClaim: string = identity.getClaimValue(AuthenticationConstants.AuthorizedParty); if (!appZClaim) { // No claim around AppID. Not Authorized. throw new AuthenticationError( - 'Unauthorized. "azp" claim is required on AseChannel Token version "2.0".', + 'Unauthorized. "azp" claim is required on Emulator Token version "2.0".', StatusCodes.UNAUTHORIZED ); } @@ -145,7 +147,7 @@ export namespace AseChannelValidation { } else { // Unknown Version. Not Authorized. throw new AuthenticationError( - `Unauthorized. Unknown AseChannel Token version "${versionClaim}".`, + `Unauthorized. Unknown Emulator Token version "${versionClaim}".`, StatusCodes.UNAUTHORIZED ); } diff --git a/libraries/botframework-connector/src/auth/jwtTokenValidation.ts b/libraries/botframework-connector/src/auth/jwtTokenValidation.ts index 6892598485..be593f6b6f 100644 --- a/libraries/botframework-connector/src/auth/jwtTokenValidation.ts +++ b/libraries/botframework-connector/src/auth/jwtTokenValidation.ts @@ -129,7 +129,6 @@ export namespace JwtTokenValidation { authConfig: AuthenticationConfiguration, serviceUrl: string ): Promise { - if (AseChannelValidation.isTokenFromAseChannel(channelId)) { return AseChannelValidation.authenticateAseChannelToken(authHeader); } diff --git a/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts b/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts index b8bf0e81c7..21d14f02ce 100644 --- a/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts +++ b/libraries/botframework-connector/src/auth/parameterizedBotFrameworkAuthentication.ts @@ -271,7 +271,6 @@ export class ParameterizedBotFrameworkAuthentication extends BotFrameworkAuthent channelId: string, serviceUrl: string ): Promise { - if (AseChannelValidation.isTokenFromAseChannel(channelId)) { return AseChannelValidation.authenticateAseChannelToken(authHeader); } diff --git a/libraries/botframework-connector/tests/auth/aseChannelValidation.test.js b/libraries/botframework-connector/tests/auth/aseChannelValidation.test.js index d886689762..5d2c167d1c 100644 --- a/libraries/botframework-connector/tests/auth/aseChannelValidation.test.js +++ b/libraries/botframework-connector/tests/auth/aseChannelValidation.test.js @@ -1,46 +1,67 @@ -const { AseChannelValidation, GovernmentConstants, AuthenticationConstants, BetweenBotAndAseChannelTokenValidationParameters } = require('../..'); +const { + AseChannelValidation, + GovernmentConstants, + AuthenticationConstants, + BetweenBotAndAseChannelTokenValidationParameters, +} = require('../..'); const assert = require('assert'); describe('AseChannelTestSuite', function () { describe('AseChannelTestCase', function () { - it('ValidationMetadataUrlTest_AseChannel_USGov', function () { - let config = { + const config = { ChannelService: GovernmentConstants.ChannelService, - } + }; AseChannelValidation.init(config); - assert.strictEqual(AseChannelValidation.MetadataUrl, GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl); - + assert.strictEqual( + AseChannelValidation.MetadataUrl, + GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl + ); }); it('ValidationMetadataUrlTest_AseChannel_Public', function () { - let config = {} + const config = {}; AseChannelValidation.init(config); - assert.strictEqual(AseChannelValidation.MetadataUrl, AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl); + assert.strictEqual( + AseChannelValidation.MetadataUrl, + AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl + ); }); it('ValidationIssueUrlTest_AseChannel', function () { - let config = { - MicrosoftAppTenantId: "testTenantId" - } + const config = { + MicrosoftAppTenantId: 'testTenantId', + }; AseChannelValidation.init(config); - let tenantIds = - [ - "testTenantId", - "f8cdef31-a31e-4b4a-93e4-5f571e91255a", // US Gov MicrosoftServices.onmicrosoft.us - "d6d49420-f39b-4df7-a1dc-d59a935871db" // Public botframework.com - ]; + const tenantIds = [ + 'testTenantId', + 'f8cdef31-a31e-4b4a-93e4-5f571e91255a', // US Gov MicrosoftServices.onmicrosoft.us + 'd6d49420-f39b-4df7-a1dc-d59a935871db', // Public botframework.com + ]; tenantIds.forEach(function (tmpId) { - assert.strictEqual(true, BetweenBotAndAseChannelTokenValidationParameters.issuer.includes(`https://sts.windows.net/${tmpId}/`)); - assert.strictEqual(true, BetweenBotAndAseChannelTokenValidationParameters.issuer.includes(`https://login.microsoftonline.com/${tmpId}/v2.0`)); - assert.strictEqual(true, BetweenBotAndAseChannelTokenValidationParameters.issuer.includes(`https://login.microsoftonline.us/${tmpId}/v2.0`)); - }) + assert.strictEqual( + true, + BetweenBotAndAseChannelTokenValidationParameters.issuer.includes( + `https://sts.windows.net/${tmpId}/` + ) + ); + assert.strictEqual( + true, + BetweenBotAndAseChannelTokenValidationParameters.issuer.includes( + `https://login.microsoftonline.com/${tmpId}/v2.0` + ) + ); + assert.strictEqual( + true, + BetweenBotAndAseChannelTokenValidationParameters.issuer.includes( + `https://login.microsoftonline.us/${tmpId}/v2.0` + ) + ); + }); }); it('ValidationChannelIdTest_AseChannel', function () { - assert.strictEqual(true, AseChannelValidation.isTokenFromAseChannel("AseChannel")); + assert.strictEqual(true, AseChannelValidation.isTokenFromAseChannel('AseChannel')); }); }); }); - -