public async Task AcceptAllowedCallersArray(string allowedCallerClaimId, IList <string> allowList)
        {
            var validator = new AllowedSkillsClaimsValidator(allowList);

            if (allowedCallerClaimId != null)
            {
                var claims = CreateCallerClaims(allowedCallerClaimId);

                if (allowList != null)
                {
                    if (allowList.Contains(allowedCallerClaimId) || allowList.Contains("*"))
                    {
                        await validator.ValidateClaimsAsync(claims);
                    }
                    else
                    {
                        await ValidateUnauthorizedAccessException(allowedCallerClaimId, validator, claims);
                    }
                }
                else
                {
                    await ValidateUnauthorizedAccessException(allowedCallerClaimId, validator, claims);
                }
            }
        }
示例#2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            // Register the skills configuration class
            services.AddSingleton <SkillsConfiguration>();

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton(sp =>
            {
                var allowedSkills = sp.GetService <SkillsConfiguration>().Skills.Values.Select(s => s.AppId).ToList();

                var claimsValidator = new AllowedSkillsClaimsValidator(allowedSkills);

                // If TenantId is specified in config, add the tenant as a valid JWT token issuer for Bot to Skill conversation.
                // The token issuer for MSI and single tenant scenarios will be the tenant where the bot is registered.
                var validTokenIssuers = new List <string>();
                var tenantId          = sp.GetService <IConfiguration>().GetSection(MicrosoftAppCredentials.MicrosoftAppTenantIdKey)?.Value;

                if (!string.IsNullOrWhiteSpace(tenantId))
                {
                    // For SingleTenant/MSI auth, the JWT tokens will be issued from the bot's home tenant.
                    // Therefore, these issuers need to be added to the list of valid token issuers for authenticating activity requests.
                    validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidTokenIssuerUrlTemplateV1, tenantId));
                    validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidTokenIssuerUrlTemplateV2, tenantId));
                    validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV1, tenantId));
                    validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV2, tenantId));
                }

                return(new AuthenticationConfiguration
                {
                    ClaimsValidator = claimsValidator,
                    ValidTokenIssuers = validTokenIssuers
                });
            });

            // Create the Bot Framework Authentication to be used with the Bot Adapter.
            services.AddSingleton <BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();

            // Register the Bot Framework Adapter with error handling enabled.
            // Note: some classes use the base BotAdapter so we add an extra registration that pulls the same instance.
            services.AddSingleton <CloudAdapter, AdapterWithErrorHandler>();
            services.AddSingleton <IBotFrameworkHttpAdapter>(sp => sp.GetService <CloudAdapter>());
            services.AddSingleton <BotAdapter>(sp => sp.GetService <CloudAdapter>());

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddSingleton <ChannelServiceHandlerBase, CloudSkillHandler>();

            // Register the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
            services.AddSingleton <IStorage, MemoryStorage>();

            // Register Conversation state (used by the Dialog system itself).
            services.AddSingleton <ConversationState>();

            // Register the bot as a transient. In this case the ASP Controller is expecting an IBot.
            services.AddTransient <IBot, RootBot>();
        }
        private static async Task ValidateUnauthorizedAccessException(string allowedCallerClaimId, AllowedSkillsClaimsValidator validator, List <Claim> claims)
        {
            Exception ex = await Assert.ThrowsAsync <UnauthorizedAccessException>(() => validator.ValidateClaimsAsync(claims));

            Assert.Contains(allowedCallerClaimId, ex.Message);
        }