Beispiel #1
0
        private async Task <ClaimsIdentity> RunTestCase(IConfigurationRetriever <IDictionary <string, HashSet <string> > > configRetriever, string[] requiredEndorsements = null)
        {
            var tokenExtractor = new JwtTokenExtractor(
                emptyClient,
                EmulatorValidation.ToBotFromEmulatorTokenValidationParameters,
                AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl,
                AuthenticationConstants.AllowedSigningAlgorithms,
                new ConfigurationManager <IDictionary <string, HashSet <string> > >("http://test", configRetriever));

            string header = $"Bearer {await new MicrosoftAppCredentials(EnvironmentConfig.TestAppId(), EnvironmentConfig.TestAppPassword()).GetTokenAsync()}";

            return(await tokenExtractor.GetIdentityAsync(header, "testChannel", requiredEndorsements));
        }
        private static Task <ClaimsIdentity> BuildExtractorAndValidateToken(X509Certificate2 cert, TokenValidationParameters validationParameters = null)
        {
            // Custom validation parameters that allow us to test the extractor logic
            var tokenValidationParams = validationParameters ?? CreateTokenValidationParameters(cert);

            // Build Jwt extractor to be tested
            var tokenExtractor = new JwtTokenExtractor(
                Client,
                tokenValidationParams,
                "https://login.botframework.com/v1/.well-known/openidconfiguration",
                AuthenticationConstants.AllowedSigningAlgorithms);

            var token = CreateTokenForCertificate(cert);

            return(tokenExtractor.GetIdentityAsync($"Bearer {token}", "test"));
        }
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            MicrosoftAppId = MicrosoftAppId ?? BotOptions?.Authentication?.MicrosoftAppId ?? string.Empty;

            if (Debugger.IsAttached && String.IsNullOrEmpty(MicrosoftAppId))
            {
                // then auth is disabled
                await next();

                return;
            }


            var tokenExtractor = new JwtTokenExtractor(JwtConfig.GetToBotFromChannelTokenValidationParameters(MicrosoftAppId), OpenIdConfigurationUrl);
            var request        = context.HttpContext.GetHttpRequestMessage();
            var identity       = await tokenExtractor.GetIdentityAsync(request);

            // No identity? If we're allowed to, fall back to MSA
            // This code path is used by the emulator
            if (identity == null && !DisableSelfIssuedTokens)
            {
                tokenExtractor = new JwtTokenExtractor(JwtConfig.ToBotFromMSATokenValidationParameters, JwtConfig.ToBotFromMSAOpenIdMetadataUrl);
                identity       = await tokenExtractor.GetIdentityAsync(request);

                // Check to make sure the app ID in the token is ours
                if (identity != null)
                {
                    // If it doesn't match, throw away the identity
                    if (tokenExtractor.GetBotIdFromClaimsIdentity(identity) != MicrosoftAppId)
                    {
                        identity = null;
                    }
                }
            }

            // Still no identity? Fail out.
            if (identity == null)
            {
                var host = request.RequestUri.DnsSafeHost;
                context.HttpContext.Response.Headers.Add("WWW-Authenticate", $"Bearer realm=\"{host}\"");
                context.Result = new StatusCodeResult(StatusCodes.Status401Unauthorized);
                return;
            }

            var activity = context.ActionArguments.Select(t => t.Value).OfType <Activity>().FirstOrDefault();

            if (activity != null)
            {
                MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl);
            }
            else
            {
                // No model binding to activity check if we can find JObject or JArray
                var obj = context.ActionArguments.Where(t => t.Value is JObject || t.Value is JArray).Select(t => t.Value).FirstOrDefault();
                if (obj != null)
                {
                    Activity[] activities = (obj is JObject) ? new Activity[] { ((JObject)obj).ToObject <Activity>() } : ((JArray)obj).ToObject <Activity[]>();
                    foreach (var jActivity in activities)
                    {
                        if (!string.IsNullOrEmpty(jActivity.ServiceUrl))
                        {
                            MicrosoftAppCredentials.TrustServiceUrl(jActivity.ServiceUrl);
                        }
                    }
                }
                else
                {
                    Trace.TraceWarning("No activity in the Bot Authentication Action Arguments");
                }
            }

            var principal = new ClaimsPrincipal(identity);

            Thread.CurrentPrincipal = principal;
            // Inside of ASP.NET this is required
            if (context.HttpContext != null)
            {
                context.HttpContext.User = principal;
            }
            await next();
        }
        private static async Task <Response> GetResponse(INancyModule module, NancyContext ctx)
        {
            MicrosoftAppId = MicrosoftAppId ??
                             ConfigurationManager.AppSettings[MicrosoftAppIdSettingName ?? "MicrosoftAppId"];

            if (Debugger.IsAttached && string.IsNullOrEmpty(MicrosoftAppId))
            {
                // then auth is disabled
                return(null);
            }

            var tokenExtractor =
                new JwtTokenExtractor(JwtConfig.GetToBotFromChannelTokenValidationParameters(MicrosoftAppId),
                                      OpenIdConfigurationUrl);

            var identity = await tokenExtractor.GetIdentityAsync(ctx.Request.Headers.Authorization);

            // No identity? If we're allowed to, fall back to MSA
            // This code path is used by the emulator
            if (identity == null && !DisableSelfIssuedTokens)
            {
                tokenExtractor = new JwtTokenExtractor(JwtConfig.ToBotFromMSATokenValidationParameters,
                                                       JwtConfig.ToBotFromMSAOpenIdMetadataUrl);

                identity = await tokenExtractor.GetIdentityAsync(ctx.Request.Headers.Authorization);

                // Check to make sure the app ID in the token is ours
                if (identity != null)
                {
                    // If it doesn't match, throw away the identity
                    if (tokenExtractor.GetBotIdFromClaimsIdentity(identity) != MicrosoftAppId)
                    {
                        identity = null;
                    }
                }
            }

            // Still no identity? Fail out.
            if (identity == null)
            {
                //https://github.com/Microsoft/BotBuilder/blob/master/CSharp/Library/Microsoft.Bot.Connector/JwtTokenExtractor.cs#L87
                //tokenExtractor.GenerateUnauthorizedResponse(actionContext);
                return(new Response
                {
                    StatusCode = HttpStatusCode.Unauthorized,
                    Headers =
                        new Dictionary <string, string>()
                    {
                        { "WWW-Authenticate", $"Bearer realm=\"{ctx.Request.Url.HostName}\"" }
                    }
                });
            }

            var activity = module.Bind <Activity>();

            if (!string.IsNullOrWhiteSpace(activity.ServiceUrl))
            {
                MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl);
            }
            else
            {
                Trace.TraceWarning("No activity in the Bot Authentication Action Arguments");
            }

            ctx.CurrentUser = new ClaimsPrincipal(identity);

            return(null);
        }