public static bool IsAuthorized(HttpRequestMessage request, AuthorizationLevel level, ISecretManager secretManager, string functionName = null)
        {
            if (level == AuthorizationLevel.Anonymous)
            {
                return true;
            }

            AuthorizationLevel requestLevel = GetAuthorizationLevel(request, secretManager, functionName);
            return requestLevel >= level;
        }
        internal static AuthorizationLevel GetAuthorizationLevel(HttpRequestMessage request, ISecretManager secretManager, string functionName = null)
        {
            // TODO: Add support for validating "EasyAuth" headers

            // first see if a key value is specified via headers or query string (header takes precidence)
            IEnumerable<string> values;
            string keyValue = null;
            if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values))
            {
                keyValue = values.FirstOrDefault();
            }
            else
            {
                var queryParameters = request.GetQueryNameValuePairs().ToDictionary(p => p.Key, p => p.Value, StringComparer.OrdinalIgnoreCase);
                queryParameters.TryGetValue("code", out keyValue);
            }

            if (!string.IsNullOrEmpty(keyValue))
            {
                // see if the key specified is the master key
                HostSecretsInfo hostSecrets = secretManager.GetHostSecrets();
                if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                    Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
                {
                    return AuthorizationLevel.Admin;
                }

                // see if the key specified matches the host function key
                if (hostSecrets.FunctionKeys != null &&
                    hostSecrets.FunctionKeys.Any(k => Key.SecretValueEquals(keyValue, k.Value)))
                {
                    return AuthorizationLevel.Function;
                }

                // if there is a function specific key specified try to match against that
                if (functionName != null)
                {
                    IDictionary<string, string> functionSecrets = secretManager.GetFunctionSecrets(functionName);
                    if (functionSecrets != null &&
                        functionSecrets.Values.Any(s => Key.SecretValueEquals(keyValue, s)))
                    {
                        return AuthorizationLevel.Function;
                    }
                }
            }

            return AuthorizationLevel.Anonymous;
        }
        public WebHookReceiverManager(ISecretManager secretManager)
        {
            _secretManager = secretManager;
            _httpConfiguration = new HttpConfiguration();

            var builder = new ContainerBuilder();
            builder.RegisterInstance<IWebHookHandler>(new DelegatingWebHookHandler());
            builder.RegisterInstance<IWebHookReceiverConfig>(new DynamicWebHookReceiverConfig(secretManager));
            var container = builder.Build();

            WebHooksConfig.Initialize(_httpConfiguration);

            _httpConfiguration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            IEnumerable<IWebHookReceiver> receivers = _httpConfiguration.DependencyResolver.GetReceivers();
            _receiverLookup = receivers.ToDictionary(p => p.Name, p => p, StringComparer.OrdinalIgnoreCase);
        }
        public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings, IScriptHostFactory scriptHostFactory = null)
            : base(config, settingsManager, scriptHostFactory)
        {
            _config = config;
            _metricsLogger = new WebHostMetricsLogger();
            _exceptionHandler = new WebScriptHostExceptionHandler(this);
            _webHostSettings = webHostSettings;

            var systemEventGenerator = config.HostConfig.GetService<IEventGenerator>() ?? new EventGenerator();
            var systemTraceWriter = new SystemTraceWriter(systemEventGenerator, settingsManager, TraceLevel.Verbose);
            if (config.TraceWriter != null)
            {
                config.TraceWriter = new CompositeTraceWriter(new TraceWriter[] { config.TraceWriter, systemTraceWriter });
            }
            else
            {
                config.TraceWriter = systemTraceWriter;
            }

            _secretManager = secretManagerFactory.Create(settingsManager, config.TraceWriter, webHostSettings.SecretsPath);
        }
Exemple #5
0
        internal static async Task <(string, AuthorizationLevel)> GetAuthorizationLevelAsync(ISecretManager secretManager, string keyValue, string functionName = null)
        {
            // see if the key specified is the master key
            HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync();

            if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
            {
                return(ScriptConstants.DefaultMasterKeyName, AuthorizationLevel.Admin);
            }

            if (HasMatchingKey(hostSecrets.SystemKeys, keyValue, out string keyName))
            {
                return(keyName, AuthorizationLevel.System);
            }

            // see if the key specified matches the host function key
            if (HasMatchingKey(hostSecrets.FunctionKeys, keyValue, out keyName))
            {
                return(keyName, AuthorizationLevel.Function);
            }

            // If there is a function specific key specified try to match against that
            if (functionName != null)
            {
                IDictionary <string, string> functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName);

                if (HasMatchingKey(functionSecrets, keyValue, out keyName))
                {
                    return(keyName, AuthorizationLevel.Function);
                }
            }

            return(null, AuthorizationLevel.Anonymous);
        }
Exemple #6
0
        public static IConfigurationBuilder AddGoogleSecretManager(this IConfigurationBuilder configurationBuilder, string projectName, ISecretManager secretManager = null)
        {
            if (configurationBuilder == null)
            {
                throw new ArgumentException(nameof(configurationBuilder));
            }

            if (projectName == null)
            {
                throw new ArgumentException(nameof(projectName));
            }

            configurationBuilder.Add(new SecretManagerConfigurationSource
            {
                ProjectName   = projectName,
                SecretManager = secretManager ?? new DefaultSecretManager()
            });

            return(configurationBuilder);
        }
 public SetupController(ISecretManager secretManager, ILicenseManager licenseManager, MPService mpService)
 {
     this.licenseManager = licenseManager;
     this.secretManager  = secretManager;
     this.mpService      = mpService;
 }
 public WebScriptHostManager(ScriptHostConfiguration config, ISecretManager secretManager, WebHostSettings webHostSettings)
     : this(config, secretManager, webHostSettings, new ScriptHostFactory())
 {
 }
 public TestSecretManagerFactory(ISecretManager secretManager)
 {
     _secretManager = secretManager;
 }
Exemple #10
0
        public static async Task <bool> IsAuthorizedAsync(HttpRequestMessage request, AuthorizationLevel level, ISecretManager secretManager, string functionName = null)
        {
            if (level == AuthorizationLevel.Anonymous)
            {
                return(true);
            }

            AuthorizationLevel requestLevel = await GetAuthorizationLevelAsync(request, secretManager, functionName);

            return(requestLevel >= level);
        }
Exemple #11
0
 public KeysController(WebScriptHostManager scriptHostManager, ISecretManager secretManager)
 {
     _scriptHostManager = scriptHostManager;
     _secretManager     = secretManager;
 }
Exemple #12
0
        private bool GetAuthorizationLevelAsync_CalledWithSingleThreadedContext_DoesNotDeadlock(ISecretManager secretManager)
        {
            var resetEvent = new ManualResetEvent(false);

            var thread = new Thread(() =>
            {
                HttpRequestMessage request = new HttpRequestMessage();
                request = new HttpRequestMessage();
                request.Headers.Add(AuthorizationLevelAttribute.FunctionsKeyHeaderName, TestFunctionKeyValue1);

                var context = new SingleThreadedSynchronizationContext(true);
                SynchronizationContext.SetSynchronizationContext(context);

                AuthorizationLevelAttribute.GetAuthorizationLevelAsync(request, secretManager, functionName: "TestFunction")
                .ContinueWith(t =>
                {
                    context.Stop();

                    resetEvent.Set();
                });

                context.Run();
            });

            thread.IsBackground = true;
            thread.Start();

            bool eventSignaled = resetEvent.WaitOne(TimeSpan.FromSeconds(5));

            thread.Abort();

            return(eventSignaled);
        }
Exemple #13
0
        public override async Task <HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            HttpRequestMessage request = controllerContext.Request;

            // First see if the request maps to an HTTP function
            FunctionDescriptor function = _scriptHostManager.GetHttpFunctionOrNull(request);

            if (function == null)
            {
                return(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            // Determine the authorization level of the request
            ISecretManager secretManager      = controllerContext.Configuration.DependencyResolver.GetService <ISecretManager>();
            var            settings           = controllerContext.Configuration.DependencyResolver.GetService <WebHostSettings>();
            var            authorizationLevel = settings.IsAuthDisabled
                ? AuthorizationLevel.Admin
                : await AuthorizationLevelAttribute.GetAuthorizationLevelAsync(request, secretManager, functionName : function.Name);

            request.SetAuthorizationLevel(authorizationLevel);

            if (function.Metadata.IsExcluded ||
                (function.Metadata.IsDisabled && authorizationLevel != AuthorizationLevel.Admin))
            {
                // disabled functions are not publicly addressable w/o Admin level auth,
                // and excluded functions are also ignored here (though the check above will
                // already exclude them)
                return(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            // Dispatch the request
            HttpTriggerBindingMetadata httpFunctionMetadata = (HttpTriggerBindingMetadata)function.Metadata.InputBindings.FirstOrDefault(p => string.Compare("HttpTrigger", p.Type, StringComparison.OrdinalIgnoreCase) == 0);
            bool isWebHook = !string.IsNullOrEmpty(httpFunctionMetadata.WebHookType);
            HttpResponseMessage response = null;

            if (isWebHook)
            {
                if (authorizationLevel == AuthorizationLevel.Admin)
                {
                    // Admin level requests bypass the WebHook auth pipeline
                    response = await _scriptHostManager.HandleRequestAsync(function, request, cancellationToken);
                }
                else
                {
                    // This is a WebHook request so define a delegate for the user function.
                    // The WebHook Receiver pipeline will first validate the request fully
                    // then invoke this callback.
                    Func <HttpRequestMessage, Task <HttpResponseMessage> > invokeFunction = async(req) =>
                    {
                        // Reset the content stream before passing the request down to the function
                        Stream stream = await req.Content.ReadAsStreamAsync();

                        stream.Seek(0, SeekOrigin.Begin);

                        return(await _scriptHostManager.HandleRequestAsync(function, req, cancellationToken));
                    };
                    response = await _webHookReceiverManager.HandleRequestAsync(function, request, invokeFunction);
                }
            }
            else
            {
                // Authorize
                if (authorizationLevel < httpFunctionMetadata.AuthLevel)
                {
                    return(new HttpResponseMessage(HttpStatusCode.Unauthorized));
                }

                // Not a WebHook request so dispatch directly
                response = await _scriptHostManager.HandleRequestAsync(function, request, cancellationToken);
            }

            return(response);
        }
 public KeysController(WebScriptHostManager scriptHostManager, ISecretManager secretManager, TraceWriter traceWriter)
 {
     _scriptHostManager = scriptHostManager;
     _secretManager = secretManager;
     _traceWriter = traceWriter.WithSource($"{ScriptConstants.TraceSourceSecretManagement}.Api");
 }
Exemple #15
0
 public WebJobsSdkExtensionHookProvider(ISecretManager secretManager)
 {
     _secretManager = secretManager;
 }
Exemple #16
0
 public TestSecretManagerProvider(ISecretManager secretManager)
 {
     _secretManager = secretManager;
 }
 public KeysController(WebScriptHostManager scriptHostManager, ISecretManager secretManager, ILoggerFactory loggerFactory)
 {
     _scriptHostManager = scriptHostManager;
     _secretManager     = secretManager;
     _logger            = loggerFactory.CreateLogger(ScriptConstants.LogCategoryKeysController);
 }
        internal static async Task <KeyAuthorizationResult> GetAuthorizationResultAsync(HttpRequestMessage request, ISecretManager secretManager,
                                                                                        Func <IDictionary <string, string>, string, string, string> matchEvaluator, string keyName = null, string functionName = null)
        {
            // first see if a key value is specified via headers or query string (header takes precedence)
            IEnumerable <string> values;
            string keyValue = null;

            if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values))
            {
                keyValue = values.FirstOrDefault();
            }
            else
            {
                var queryParameters = request.GetQueryParameterDictionary();
                queryParameters.TryGetValue("code", out keyValue);
            }

            if (!string.IsNullOrEmpty(keyValue))
            {
                // see if the key specified is the master key
                HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false);

                if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                    Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
                {
                    return(new KeyAuthorizationResult(ScriptConstants.DefaultMasterKeyName, AuthorizationLevel.Admin));
                }

                string matchedKeyName = matchEvaluator(hostSecrets.SystemKeys, keyName, keyValue);
                if (matchedKeyName != null)
                {
                    return(new KeyAuthorizationResult(matchedKeyName, AuthorizationLevel.System));
                }

                // see if the key specified matches the host function key
                matchedKeyName = matchEvaluator(hostSecrets.FunctionKeys, keyName, keyValue);
                if (matchedKeyName != null)
                {
                    return(new KeyAuthorizationResult(matchedKeyName, AuthorizationLevel.Function));
                }

                // if there is a function specific key specified try to match against that
                if (functionName != null)
                {
                    var functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName);

                    matchedKeyName = matchEvaluator(functionSecrets, keyName, keyValue);
                    if (matchedKeyName != null)
                    {
                        return(new KeyAuthorizationResult(matchedKeyName, AuthorizationLevel.Function));
                    }
                }
            }

            return(new KeyAuthorizationResult(null, AuthorizationLevel.Anonymous));
        }
 internal static Task <KeyAuthorizationResult> GetAuthorizationResultAsync(HttpRequestMessage request, ISecretManager secretManager, string keyName = null, string functionName = null)
 {
     return(GetAuthorizationResultAsync(request, secretManager, GetKeyMatchOrNull, keyName, functionName));
 }
Exemple #20
0
        internal static async Task <(string, AuthorizationLevel)> GetAuthorizationKeyInfoAsync(HttpRequest request, ISecretManager secretManager)
        {
            // first see if a key value is specified via headers or query string (header takes precedence)
            string keyValue = null;

            if (request.Headers.TryGetValue(FunctionsKeyHeaderName, out StringValues values))
            {
                keyValue = values.First();
            }
            else if (request.Query.TryGetValue("code", out values))
            {
                keyValue = values.First();
            }

            if (!string.IsNullOrEmpty(keyValue))
            {
                // see if the key specified is the master key
                HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false);

                if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                    Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
                {
                    return(ScriptConstants.DefaultMasterKeyName, AuthorizationLevel.Admin);
                }

                if (HasMatchingKey(hostSecrets.SystemKeys, keyValue, out string keyName))
                {
                    return(keyName, AuthorizationLevel.System);
                }

                // see if the key specified matches the host function key
                if (HasMatchingKey(hostSecrets.FunctionKeys, keyValue, out keyName))
                {
                    return(keyName, AuthorizationLevel.Function);
                }

                // If there is a function specific key specified try to match against that
                IFunctionExecutionFeature executionFeature = request.HttpContext.Features.Get <IFunctionExecutionFeature>();
                if (executionFeature != null)
                {
                    IDictionary <string, string> functionSecrets = await secretManager.GetFunctionSecretsAsync(executionFeature.Descriptor.Name);

                    if (HasMatchingKey(functionSecrets, keyValue, out keyName))
                    {
                        return(keyName, AuthorizationLevel.Function);
                    }
                }
            }

            return(null, AuthorizationLevel.Anonymous);
        }
 public MaintenanceController(ISecretManager secretManager)
 {
     this.secretManager = secretManager;
 }
Exemple #22
0
 public YouTubeChannelVideos(IHttpWrapper httpWrapper, IAppCache cache, ILogger <YouTubeChannelVideos> logger, IFileSystemWrapper fileSystemWrapper, ISecretManager secretManager)
 {
     _httpWrapper       = httpWrapper;
     _cache             = cache;
     _logger            = logger;
     _fileSystemWrapper = fileSystemWrapper;
     _secretManager     = secretManager;
 }
Exemple #23
0
 internal static Task <AuthorizationLevel> GetAuthorizationLevelAsync(HttpRequestMessage request, ISecretManager secretManager, string functionName = null)
 {
     return(GetAuthorizationLevelAsync(request, secretManager, HasMatchingKey, functionName));
 }
Exemple #24
0
        public static bool IsAuthorized(HttpRequestMessage request, AuthorizationLevel level, ISecretManager secretManager, string functionName = null)
        {
            if (level == AuthorizationLevel.Anonymous)
            {
                return(true);
            }

            AuthorizationLevel requestLevel = GetAuthorizationLevel(request, secretManager, functionName);

            return(requestLevel >= level);
        }
 public KeysController(WebScriptHostManager scriptHostManager, ISecretManager secretManager, TraceWriter traceWriter)
 {
     _scriptHostManager = scriptHostManager;
     _secretManager     = secretManager;
     _traceWriter       = traceWriter.WithSource($"{ScriptConstants.TraceSourceSecretManagement}.Api");
 }
Exemple #26
0
 public SecretsManagerConfigurationProvider(SecretManagerServiceClient secretManagerServiceClient, string projectName, ISecretManager manager)
 {
     this.secretManagerServiceClient = secretManagerServiceClient;
     this.projectName = projectName;
     this.manager     = manager;
 }
Exemple #27
0
        internal static async Task <AuthorizationLevel> GetAuthorizationLevelAsync(HttpRequestMessage request, ISecretManager secretManager, string functionName = null)
        {
            // TODO: Add support for validating "EasyAuth" headers

            // first see if a key value is specified via headers or query string (header takes precedence)
            IEnumerable <string> values;
            string keyValue = null;

            if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values))
            {
                keyValue = values.FirstOrDefault();
            }
            else
            {
                var queryParameters = request.GetQueryParameterDictionary();
                queryParameters.TryGetValue("code", out keyValue);
            }

            if (!string.IsNullOrEmpty(keyValue))
            {
                // see if the key specified is the master key
                HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false);

                if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                    Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
                {
                    return(AuthorizationLevel.Admin);
                }

                // see if the key specified matches the host function key
                if (hostSecrets.FunctionKeys != null &&
                    hostSecrets.FunctionKeys.Any(k => Key.SecretValueEquals(keyValue, k.Value)))
                {
                    return(AuthorizationLevel.Function);
                }

                // if there is a function specific key specified try to match against that
                if (functionName != null)
                {
                    IDictionary <string, string> functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName);

                    if (functionSecrets != null &&
                        functionSecrets.Values.Any(s => Key.SecretValueEquals(keyValue, s)))
                    {
                        return(AuthorizationLevel.Function);
                    }
                }
            }

            return(AuthorizationLevel.Anonymous);
        }
Exemple #28
0
        public async Task Invoke(HttpContext context, [FromServices] SiteConfig siteConfig, [FromServices] ISecretManager secretManager)
        {
            if (!secretManager.IsSet() && !IsPathInWhiteList(context.Request.Path))
            {
                var hostUrl  = HostUrlHelper.GetHostUrl(context.Request, siteConfig.BaseUrlPrefix);
                var model    = ErrorsModel.Create(string.Format(GlobalResources.SecretIsNotSetVisit_0_ForSetup, $"{hostUrl}/setup"));
                var response = JsonConvert.SerializeObject(model);

                context.Response.StatusCode    = StatusCodes.Status412PreconditionFailed;
                context.Response.ContentType   = "application/json";
                context.Response.ContentLength = response.Length;

                await context.Response.WriteAsync(response);

                return;
            }

            await _next.Invoke(context);
        }
 public DynamicWebHookReceiverConfig(ISecretManager secretManager)
 {
     _secretManager = secretManager;
 }
        public async Task RotateSecretAsync(Secret secret, CancellationToken token)
        {
            if (null == secret)
            {
                throw new ArgumentNullException(nameof(secret));
            }

            if (secret.SecretType == SecretType.Attached)
            {
                if (null == secret.Configuration)
                {
                    throw new ArgumentNullException(nameof(secret.Configuration));
                }
                if (null == secret.Configuration.Policy)
                {
                    throw new ArgumentException(nameof(secret.Configuration.Policy));
                }
            }

            _logger?.LogInformation($"Attempting to rotate secret {secret.Uri}.");

            ISecretManager provider = null;

            try
            {
                ServiceType effectiveServiceType = (secret.Configuration == null) ? ServiceType.Unspecified : secret.Configuration.ServiceType;
                provider = CreateSecretManagementProvider(effectiveServiceType);
            }
            catch (InvalidOperationException)
            {
                _logger.LogWarning($"Unable to locate SecretManager for {secret.Configuration.ServiceType}");
                throw;
            }

            Key rotated = null;

            try
            {
                rotated = await provider.RotateSecretAsync(secret, token);

                _logger?.LogInformation($"Rotated secret {secret.Uri}");
            }
            catch (Exception ex)
            {
                _logger?.LogWarning($"Unable to rotate secret {secret.Uri}. Exception: {ex.Message}");
                throw;
            }

            if (null != rotated)
            {
                _logger?.LogInformation($"Updating secret metadata for {secret.Uri}");
                //update Key.Name into secret record?
                secret.CurrentKeyName = rotated.Name;
                secret.Version        = rotated.SecretVersion;
                secret.LastRotatedOn  = DateTime.UtcNow;
                try
                {
                    await _dataProvider.SaveSecretAsync(secret, token); //Save secret

                    _logger?.LogInformation($"Updated secret metadata for {secret.Uri}");
                }
                catch (Exception ex)
                {
                    _logger?.LogWarning($"Unable to update secret metadata {secret.Uri}. Exception: {ex.Message}");
                    throw;
                }
            }
        }
 public DynamicWebHookReceiverConfig(ISecretManager secretManager)
 {
     _secretManager = secretManager;
 }
 public TokenManager(HttpClient client, IConfiguration configuration, ISecretManager secretManager)
 {
     _client        = client;
     _configuration = configuration;
     _secretManager = secretManager;
 }
 public GetSecretCommand(ISecretManager secretManager, IModule module, string secretId)
 {
     this.secretManager = secretManager;
     this.module        = module;
     this.secretId      = secretId;
 }
 public PgpService(ISecretManager secretManager, ILogger <PgpService> log)
 {
     _pgp           = new PGP();
     _secretManager = secretManager;
     Log            = log;
 }