Skip to content

Commit

Permalink
Implementing multi-key support
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiocav committed Sep 28, 2016
1 parent d485616 commit 31cd763
Show file tree
Hide file tree
Showing 40 changed files with 1,749 additions and 114 deletions.
8 changes: 7 additions & 1 deletion src/WebJobs.Script.WebHost/App_Data/secrets/HttpTrigger.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"key": "hyexydhln844f2mb7hgsup2yf8dowlb0885mbiq1"
"keys": [
{
"name": "default",
"value": "hyexydhln844f2mb7hgsup2yf8dowlb0885mbiq1",
"encrypted": false
}
]
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"key": "827bdzxhqy3xc62cxa2hmfsh6gxzhg30s5pi64tu"
"keys": [
{
"name": "default",
"value": "827bdzxhqy3xc62cxa2hmfsh6gxzhg30s5pi64tu",
"encrypted": false
}
]
}
13 changes: 12 additions & 1 deletion src/WebJobs.Script.WebHost/App_Data/secrets/WebHook-Generic.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
{
"key": "1388a6b0d05eca2237f10e4a4641260b0a08f3a5"
"keys": [
{
"name": "default",
"value": "1388a6b0d05eca2237f10e4a4641260b0a08f3a5",
"encrypted": false
},
{
"name": "testclient",
"value": "1388a6b0d05eca2237f10e4a4641260b0a08f3a6",
"encrypted": false
}
]
}
17 changes: 14 additions & 3 deletions src/WebJobs.Script.WebHost/App_Data/secrets/host.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
{
"masterKey": "t8laajal0a1ajkgzoqlfv5gxr4ebhqozebw4qzdy",
"functionKey": "zlnu496ve212kk1p84ncrtdvmtpembduqp25ajjc"
}
"masterKey": {
"name": "master",
"value": "t8laajal0a1ajkgzoqlfv5gxr4ebhqozebw4qzdy",
"encrypted": false
},
"functionKeys": [
{
"name": "default",
"value": "zlnu496ve212kk1p84ncrtdvmtpembduqp25ajjc",
"encrypted": false
}
]

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"key": "8CTs65hqBcX3DVddZOGkPoksSaIDRck9byv1ATWbqJuOb9h8MrVZzA=="
"keys": [
{
"name": "default",
"value": "8CTs65hqBcX3DVddZOGkPoksSaIDRck9byv1ATWbqJuOb9h8MrVZzA==",
"encrypted": false
}
]
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"key": "N5rUeecvsqN1Q1lDciR7P8kn3KkQtnNJVlK7H5bev0jO7r5DbAZgvA=="
"keys": [
{
"name": "default",
"value": "N5rUeecvsqN1Q1lDciR7P8kn3KkQtnNJVlK7H5bev0jO7r5DbAZgvA==",
"encrypted": false
}
]
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"key": "yKjiimZjC1FQoGlaIj8TUfGltnPE/f2LhgZNq6Fw9/XfAOGHmSgUlQ=="
"keys": [
{
"name": "default",
"value": "yKjiimZjC1FQoGlaIj8TUfGltnPE/f2LhgZNq6Fw9/XfAOGHmSgUlQ==",
"encrypted": false
}
]
}
8 changes: 1 addition & 7 deletions src/WebJobs.Script.WebHost/App_Start/WebHostResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,7 @@ private static ScriptHostConfiguration GetScriptHostConfiguration(string scriptP
return scriptHostConfig;
}

private static SecretManager GetSecretManager(string secretsPath)
{
var secretManager = new SecretManager(secretsPath);
secretManager.GetHostSecrets();

return secretManager;
}
private static SecretManager GetSecretManager(string secretsPath) => new SecretManager(secretsPath);

public void Dispose()
{
Expand Down
43 changes: 6 additions & 37 deletions src/WebJobs.Script.WebHost/Filters/AuthorizationLevelAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,26 @@ internal static AuthorizationLevel GetAuthorizationLevel(HttpRequestMessage requ
if (!string.IsNullOrEmpty(keyValue))
{
// see if the key specified is the master key
HostSecrets hostSecrets = secretManager.GetHostSecrets();
HostSecretsInfo hostSecrets = secretManager.GetHostSecrets();
if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
SecretEqual(keyValue, hostSecrets.MasterKey))
Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
{
return AuthorizationLevel.Admin;
}

// see if the key specified matches the host function key
if (!string.IsNullOrEmpty(hostSecrets.FunctionKey) &&
SecretEqual(keyValue, hostSecrets.FunctionKey))
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)
{
FunctionSecrets functionSecrets = secretManager.GetFunctionSecrets(functionName);
Dictionary<string, string> functionSecrets = secretManager.GetFunctionSecrets(functionName);
if (functionSecrets != null &&
!string.IsNullOrEmpty(functionSecrets.Key) &&
SecretEqual(keyValue, functionSecrets.Key))
functionSecrets.Values.Any(s => Key.SecretValueEquals(keyValue, s)))
{
return AuthorizationLevel.Function;
}
Expand All @@ -98,35 +97,5 @@ internal static AuthorizationLevel GetAuthorizationLevel(HttpRequestMessage requ

return AuthorizationLevel.Anonymous;
}

/// <summary>
/// Provides a time consistent comparison of two secrets in the form of two strings.
/// This prevents security attacks that attempt to determine key values based on response
/// times.
/// </summary>
/// <param name="inputA">The first secret to compare.</param>
/// <param name="inputB">The second secret to compare.</param>
/// <returns>Returns <c>true</c> if the two secrets are equal, <c>false</c> otherwise.</returns>
[MethodImpl(MethodImplOptions.NoOptimization)]
private static bool SecretEqual(string inputA, string inputB)
{
if (ReferenceEquals(inputA, inputB))
{
return true;
}

if (inputA == null || inputB == null || inputA.Length != inputB.Length)
{
return false;
}

bool areSame = true;
for (int i = 0; i < inputA.Length; i++)
{
areSame &= inputA[i] == inputB[i];
}

return areSame;
}
}
}
10 changes: 10 additions & 0 deletions src/WebJobs.Script.WebHost/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseMetricsPerFunctionEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseFunctionsInfoEvent(System.String,System.String,System.String,System.String,System.String,System.Boolean)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseFunctionExecutionEvent(System.String,System.String,System.Int32,System.String,System.String,System.String,System.Int64,System.Boolean)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ms", Scope = "member", Target = "WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseMetricsPerFunctionEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ms", Scope = "member", Target = "WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseMetricsPerFunctionEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.AutofacBootstrap.#Initialize(Autofac.ContainerBuilder,Microsoft.Azure.WebJobs.Script.WebHost.WebHostSettings)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Controllers.HomeController.#Get()")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseFunctionsMetricEvent(System.String,System.Int64,System.Int64,System.String)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ms", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseMetricsPerFunctionEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ms", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseMetricsPerFunctionEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseMetricsPerFunctionEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseFunctionsInfoEvent(System.String,System.String,System.String,System.String,System.String,System.Boolean)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IMetricsEventGenerator.#RaiseFunctionExecutionEvent(System.String,System.String,System.Int32,System.String,System.String,System.String,System.Int64,System.Boolean)")]
Expand All @@ -44,5 +48,11 @@
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "_activeReceiverManager", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.WebHostResolver.#Dispose()")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "_standbyHostManager", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.WebHostResolver.#Dispose()")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "_standbyReceiverManager", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.WebHostResolver.#Dispose()")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.HostSecrets.#FunctionKeys")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.HostSecrets.#Version")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.HostSecrets.#Version")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.HostSecretsInfo.#FunctionKeys")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.SecretManager.#.ctor(System.String,Microsoft.Azure.WebJobs.Script.WebHost.IKeyValueConverterFactory)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.FunctionSecrets.#Keys")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ms", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IEventGenerator.#LogFunctionExecutionAggregateEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ms", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.IEventGenerator.#LogFunctionExecutionAggregateEvent(System.String,System.String,System.Int64,System.Int64,System.Int64,System.Int64)")]
4 changes: 3 additions & 1 deletion src/WebJobs.Script.WebHost/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Expand All @@ -17,4 +18,5 @@
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("63c9b2f4-f122-4acc-968f-9b8f0880a72f")]

[assembly: InternalsVisibleTo("Microsoft.Azure.WebJobs.Script.Tests")]
[assembly: InternalsVisibleTo("Microsoft.Azure.WebJobs.Script.Tests")]
[assembly: NeutralResourcesLanguage("en-US")]
Loading

0 comments on commit 31cd763

Please sign in to comment.